2012-03-25 4 views
4

EDIT: Я подтвердил, что это ошибка в Python. Это ошибка http://bugs.python.org/issue10332 (я подал новую ошибку, в ответ на которую сопровождающий указал мне на 10332). Я скопировал многопроцессорный каталог из исходного репозитория Python в свой каталог проектов, и тестовый файл теперь работает правильно.многопроцессор python с maxtasksperchild

Эта, казалось бы, простая программа не работает для меня, если я не удалю параметр maxtasksperchild. Что я делаю не так?

from multiprocessing import Pool 
import os 
import sys 

def f(x): 
    print "pid: ", os.getpid(), " got: ", x 
    sys.stdout.flush() 
    return [x, x+1] 

def cb(r): 
    print "got result: ", r 

if __name__ == '__main__': 
    pool = Pool(processes=1, maxtasksperchild=9) 
    keys = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    result = pool.map_async(f, keys, chunksize=1, callback=cb) 
    pool.close() 
    pool.join() 

Когда я бегу, я получаю:

$ python doit.py 
pid: 6409 got: 1 
pid: 6409 got: 2 
pid: 6409 got: 3 
pid: 6409 got: 4 
pid: 6409 got: 5 
pid: 6409 got: 6 
pid: 6409 got: 7 
pid: 6409 got: 8 
pid: 6409 got: 9 

И он висит. То есть новый рабочий для обработки 10-го элемента не генерируется.

В другом терминале, я вижу:

$ ps -C python 
    PID TTY   TIME CMD 
6408 pts/11 00:00:00 python 
6409 pts/11 00:00:00 python <defunct> 

Это делается на Ubuntu 11.10 работает питона 2.7.2+ (установлен с Ubuntu пакетов).

+0

Я думаю, что это ошибка в python. Мой вызов pool.close() (который, как говорят документы, должен вызвать до вызова пула pool.join()), устанавливает флаг pool._state в CLOSE. Функция Pool._handle_workers полагается на то, что этот флаг является «RUN» для запуска новых рабочих процессов. Обходной путь для ошибки заключается в том, чтобы спать после вызова map_async в течение примерно 10 секунд до вызова pool.close(). Я, вероятно, напишу ошибку против python. – user188012

+0

Я могу подтвердить этот hevaiour. Имея python 2.7.2, столкнулся с той же проблемой с maxtasksperchild = 1. Скрипт повесился на finall pool.join() после того, как все задачи были успешно выполнены, оставив все дочерние процессы зомби (). Удаление этого параметра из создания пула - разрешило проблему. –

+0

было ли это когда-либо разрешено? – user3467349

ответ

-2

Я никогда не использовал многопоточность в Python, но я предполагаю, что вы хотите сделать maxtasksperchild = 10 на этой линии: pool = Pool(processes=1, maxtasksperchild=9) и выходе после этого изменения:

pid: 8436 got: 1 
pid: 8436 got: 2 
pid: 8436 got: 3 
pid: 8436 got: 4 
pid: 8436 got: 5 
pid: 8436 got: 6 
pid: 8436 got: 7 
pid: 8436 got: 8 
pid: 8436 got: 9 
pid: 8436 got: 10 
got result: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11]] 
+0

Приятно слышать, что вы также получаете тот же результат, что и я для 9. Но то, что вы написали, не отвечает на мой вопрос. maxtasksperchild = 10 работает, потому что нет необходимости в обновлении рабочего процесса. Почему не работает maxtasksperchild = 9? – user188012

0

maxtasksperchild означает один обработку выполнить максимальное количество задач .

0

Эта проблема исправлена ​​в python3.

pid: 18316 got: 1 
pid: 18316 got: 2 
pid: 18316 got: 3 
pid: 18316 got: 4 
pid: 18316 got: 5 
pid: 18316 got: 6 
pid: 18316 got: 7 
pid: 18316 got: 8 
pid: 18316 got: 9 
pid: 18317 got: 10 
got result: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11]] 
Смежные вопросы