Python resource_tracker: процесс неожиданно умер при использовании многопроцессорного метода 'spawn' в чистой среде - PullRequest
0 голосов
/ 29 мая 2020

TL; DR: это ожидаемое поведение?

Совсем не похоже на Python многопроцессорность с методом запуска 'spawn' не работает , который является ближайшим из существующих вопросов Я смог найти.

Чтобы быть точным, вот MWI, который я использую для тестирования:

import multiprocessing as mp

def fun_computation(x, output):
    acc = 0
    for i in range(x):
        acc += i * i
        output.value = acc

def main():
    shared = mp.Value("i", -1)
    proc = mp.Process(target=fun_computation, args=(100, shared))
    proc.start()
    proc.join()
    assert(shared.value >= 0)
    print(shared.value)

if __name__ == "__main__":
    mp.set_start_method('spawn')
    main()

И вот результат, который я получаю:

❯ python mptest.py
328350
❯ env -i python mptest.py
/usr/lib/python3.8/multiprocessing/resource_tracker.py:96: UserWarning: resource_tracker: process died unexpectedly, relaunching.  Some resources might leak.
  warnings.warn('resource_tracker: process died unexpectedly, '
Traceback (most recent call last):
  File "mptest.py", line 19, in <module>
    main()
  File "mptest.py", line 14, in main
    assert(shared.value >= 0)
AssertionError
❯ python -V
Python 3.8.3

Это было протестировано на последней версии Arch Linux (на момент написания). Я еще не тестировал его на Windows, и у меня нет доступа к macOS. Обычные сценарии python (например, вызов fun_computation без многопроцессорности) работают нормально.

Извините, если этот пример кажется немного запутанным; настоящая ошибка является побочным продуктом взаимодействия многих других систем, но это демонстрирует мою проблему.

TL; DR: Это ожидаемое поведение?

1 Ответ

0 голосов
/ 29 мая 2020

Начиная с python> 3.x, вы можете использовать multiprocessing.get_context (), чтобы получить объект контекста для использования нескольких методов запуска:

Попробуйте следующие решения:

if __name__ == '__main__':
    shared = mp.Value("i", -1)
    ctx = mp.get_context('spawn')
    q = ctx.Queue() #here q=100
    p = ctx.Process(target=fun_computation, args=(q,shared))
    p.start()
    print(q.get())
    p.join()

Или:

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=7)
    pool.apply_async(fun_computation, args=(q,shared))
    pool.close()
    pool.join()
...