установить self._state в (CLOSE, TERMINATE) при использовании многопроцессного Python - PullRequest
0 голосов
/ 30 мая 2018

В настоящее время я пытаюсь использовать многопроцессорность Python.Я использую библиотеку multiprocess (НЕ multiprocessing).

У меня есть следующий код, который создает несколько вычислительных заданий и запускает его с помощью операции сопоставления:

pool = multiprocess.Pool(4)
all_responses = pool.map_async(wrapper_singlerun, range(10000))
pool.join()
pool.close()

Однако всякий раз, когда я запускаю этот фрагмент кода, я получаюследующая ошибка:

    pool.join()
  File "/Users/davidal/miniconda3/lib/python3.6/site-packages/multiprocess/pool.py", line 509, in join
    assert self._state in (CLOSE, TERMINATE)
AssertionError

У вас есть идеи, почему эта ошибка происходит?Я использовал pool.map_async раньше, но решил, что мне нужна команда pool rendez-vous.В противном случае мой компьютер создал что-то вроде вилки, которая создала слишком много потоков (по крайней мере, я так думаю ...)

Любые идеи приветствуются!

1 Ответ

0 голосов
/ 30 мая 2018

Проблема в том, что вы звоните join до close.

multiprocess, кажется, отсутствует документация , но, так какНасколько я могу судить, это в основном форк stdlib multiprocessing, который предварительно monkeypatches dill в для pickle, так что документы multiprocessing должны быть актуальны здесь.(Также в комментарии вы сказали, что можете воспроизвести проблему с помощью multiprocessing.)

Итак, Pool.join говорит:

Подождитедля рабочих процессов, чтобы выйти.Перед использованием join().

необходимо вызвать close() или terminate(). Метод close - это то, как вы отключаете сторону отправки очереди, чтобы новые задачи не могли быть добавлены.Метод join - это то, как вы ожидаете обработки всего в очереди.Ожидание истечения очереди до ее закрытия не будет работать.

Но вы звоните close после join, а не до.И первое, что join делает , это assert, который вы уже назвали close или terminate, которого у вас нет, следовательно, ошибка подтверждения.

ТакВы, вероятно, просто хотите изменить порядок этих двух вызовов.

Или, альтернативно, возможно, вы не понимали, для чего нужен join, и подумали, что вам нужно позвонить до того, как вы сможете использовать all_responses.get()или .wait().Если так - вам не нужно этого делать;get будет блокироваться до тех пор, пока не станут доступны результаты, после чего вам не понадобится join.На самом деле это чаще встречается, особенно у map и друзей (хотя примеры в документации делают это через with Pool(…) as pool: вместо ручного вызова чего-либо в пуле).

...