Python: задачи с интенсивным использованием ЦП в нескольких потоках - PullRequest
1 голос
/ 21 июня 2020

Предположим, у меня есть этот класс:

class Foo:
    def __init__(self):
        self.task1_dict = {}
        self.task2_dict = {}

    def task1(self):
        for i in range(10000000):
            # update self.task1_dict
    
    def task2(self):
        for i in range(10000000):
            # update self.task2_dict

    def run(self):
        self.task1()
        self.task2()

Задача 1 и задача 2 являются задачами с интенсивным использованием ЦП и не связаны с вводом-выводом. Они также независимы, поэтому вы можете предположить, что их одновременное выполнение является потокобезопасным.

На данный момент мой класс выполняет задачи последовательно, и я хочу изменить его, чтобы задачи выполнялись параллельно в нескольких потоках. Я использую ThreadPoolExecutor из пакета concurrent.future.

class Foo:
    ...
    def run(self):
        with ThreadPoolExecutor() as executor:
            executor.submit(self.task1)
            executor.submit(self.task2)

Проблема в том, что когда я вызываю метод run, время выполнения не уменьшается вообще и даже немного увеличивается по сравнению с последовательной версией. Я предполагаю, что это из-за того, что GIL позволяет запускать только один поток одновременно. Есть ли способ распараллелить эту программу? Может быть, способ побороть GIL и запустить 2 метода на 2 потоках? Я подумал о переходе на ProcessPoolExecutor, , но я не могу вызывать методы, поскольку методы класса не выбираются . Также, если я использую многопроцессорность, Python создаст несколько экземпляров Foo, а self.task1_dict и self.task2_dict не будут обновляться соответственно.

1 Ответ

0 голосов
/ 21 июня 2020

Вы можете использовать многопроцессорную разделяемую память , как описано здесь

...