Загадочная проблема с параллельным Python - TRANSPORT_SOCKET_TIMEOUT
Следующий код не работает для меня должным образом. Для этого требуется запустить ppserver на другом компьютере в сети, например, с помощью следующей команды:
ppserver.py -r -a -w 4
После запуска этого сервера на моем компьютере я запускаю следующий код:
import pp
import time
job_server = pp.Server(ppservers = ("*",))
job_server.set_ncpus(0)
def addOneBillion(x):
r = x
for i in xrange(10**9):
r+=1
f = open('/home/tomb/statusfile.txt', 'a')
f.write('finished at '+time.asctime()+' for job with input '+str(x)+'\n')
return r
jobs = []
jobs.append(job_server.submit(addOneBillion, (1,), (), ("time",)))
jobs.append(job_server.submit(addOneBillion, (2,), (), ("time",)))
jobs.append(job_server.submit(addOneBillion, (3,), (), ("time",)))
for job in jobs:
print job()
print 'done'
Странная часть: просматривая /home/tomb/statusfile.txt, я вижу, что он записывается несколько раз, как будто функция запускается несколько раз. Я наблюдал, что это продолжается более часа назад, и никогда не видел job()
вернуть.
Odder: Если я изменю количество итераций в определении testfunc на 10**8, функция просто запускается один раз и возвращает ожидаемый результат!
Похоже на какое-то состояние гонки? Просто использование локальных ядер работает нормально. Это с пп 1.6.0 и 1.5.7.
Обновление: около 775 000 000: я получаю противоречивые результаты: два задания повторяются один раз, в первый раз завершается.
Неделя спустя обновление: я написал свой собственный модуль параллельной обработки, чтобы обойти это, и буду избегать параллельного Python в будущем, если кто-то не поймет это - я найду время посмотреть на него еще немного (фактически углубляясь в источник код) в какой-то момент.
Месяц спустя обновление: не осталось обид, Parallel Python. Я планирую вернуться назад, как только у меня будет время для переноса моего приложения. Редактирование заголовка для отражения решения.
2 ответа
Ответ от Багиры из форума Parallel Python:
Сколько времени занимает расчет каждой работы? Посмотрите на переменную
TRANSPORT_SOCKET_TIMEOUT
в /usr/local/lib/python2.6/dist-packages/pptransport.py.Возможно, ваша работа занимает больше времени, чем указано в переменной выше. Увеличьте ценность этого и попробуйте.
Оказывается, это была именно проблема. В моем приложении я использую PP в качестве пакетного планировщика заданий, который может занять несколько минут, поэтому мне нужно настроить это. (по умолчанию было 30 с)
Может случиться так, что библиотека допускает дублирование, так как некоторые узлы отстают, и для выполнения оставшихся задач потребуется длинный хвост. Дублируя задачи, он может обойти медленные узлы, и вы должны просто взять результат, который заканчивается первым. Вы можете обойти это путем включения уникального идентификатора для каждой задачи и принять только первый, который возвращается для каждой задачи.