Python: задачи с интенсивным использованием ЦП в нескольких потоках

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

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 не будет соответственно обновляться.


person Mike Pham    schedule 21.06.2020    source источник


Ответы (1)


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

person alex_noname    schedule 21.06.2020