Использование глобально объявленного кортежа для многопроцессорной обработки Python - PullRequest
0 голосов
/ 22 ноября 2018

У меня возникли некоторые проблемы при глобальном использовании кортежа с классом многопроцессорной обработки.

У меня есть код, показанный ниже:

from multiprocessing import Pool

if __name__ == '__main__':
    jj = ()
    def f(x):
        global jj
        jj += (x*x,)

    # Section A
    #for ii in range(20):
    #    f(ii)
    #print (jj)

    # Section B
    pool = Pool(processes=4)
    pool.map(f, range(20))  
    pool.join()
    print (jj)

Если я запускаю раздел B, я получаюкортеж jj как пустой кортежОднако, если я запускаю только раздел A, я получаю кортеж длины 20.

Почему это так?

1 Ответ

0 голосов
/ 22 ноября 2018

Хорошо, поскольку Обновления глобальной переменной Python для многопроцессорных систем, не возвращаемые родительскому элементу , объясняют, что глобальное состояние не распределяется между процессами.

Вы можете поделиться состоянием, используя, например, multiprocessing.Queue.

from multiprocessing import Pool, Queue

if __name__ == "__main__":
    jj = ()
    q = Queue()

    def f(x):
        global jj
        jj += (x * x,)

    def f_multi(x):
        q.put(x * x)

    # Section A
    for ii in range(20):
        f(ii)
    print(jj)

    # Section B
    pool = Pool(processes=4)
    pool.map(f_multi, range(20))
    pool.close()

    stop = "STOP"
    q.put(stop)
    items = []
    for i in iter(q.get, stop):
        items.append(i)

    print(tuple(items))

В качестве альтернативы вы можете использовать print(tuple(sorted(items))), чтобы получить значения в том же порядке, что и Section A.4 процесса работают над задачей в Section B и, следовательно, «неупорядоченный» результат.

...