Многопроцессорная обработка Python никогда не включается - PullRequest
2 голосов
/ 11 февраля 2012

Я использую multiprocessing и, в частности, Pool, чтобы раскрутить пару «потоков», чтобы выполнить кучу медленных заданий, которые у меня есть. Однако по какой-то причине я не могу заставить основной поток вернуться, хотя все дети, кажется, умерли.

Решено: Похоже, что ответ на этот вопрос состоит в том, чтобы просто запустить несколько Process объектов вместо использования Pool. Не совсем понятно, почему, но я подозреваю, что оставшийся процесс является менеджером пула, и он не умирает, когда процессы завершаются. Если у кого-то еще есть эта проблема, это ответ.


Основная тема

pool = Pool(processes=12,initializer=thread_init)
for x in xrange(0,13):
    pool.apply_async(thread_dowork)
pool.close()
sys.stderr.write("Waiting for jobs to terminate\n")
pool.join()

xrange(0,13) - это на порядок больше, чем число процессов, потому что я думал, что у меня отключился один, а один процесс не получил работу, поэтому не умирал, и я хотел заставить его устроиться на работу. Я тоже пробовал с 12.

Функции многопроцессорной обработки

def thread_init():
    global log_out
    log_out = open('pool_%s.log'%os.getpid(),'w')
    sys.stderr = log_out
    sys.stdout = log_out
    log_out.write("Spawned")
    log_out.flush()
    log_out.write(" Complete\n")
    log_out.flush()


def thread_dowork():
    log_out.write("Entered function\n")
    log_out.flush()
    #Do Work
    log_out.write("Exiting ")
    log_out.flush()
    log_out.close()
    sys.exit(0)

Выходные данные лог-файлов для всех 12 детей:

Spawned
Complete
Entered function
Exiting

Основной поток выводит «Ожидание завершения заданий», а затем просто сидит там.

top показывает только одну копию сценария (основной, я считаю). htop показывает две копии, одна из которых сверху, а другая - что-то еще. Судя по его PID, это ни один из детей.

Кто-нибудь знает что-то, чего я не знаю?

1 Ответ

1 голос
/ 11 февраля 2012

У меня нет ответа, но я прочитал документы для Apply_async, и это, кажется, противоречит вашей заявленной проблеме ...

Обратные вызовы должны завершаться немедленно, так как в противном случае поток, который обрабатывает результаты будут заблокированы.

Я не знаком с пулом, но мне кажется, что ваш сценарий использования может быть легко обработан этим рецептом на Модуль Python недели

...