2014-08-29 5 views
0

Я использую multiprocessing для ускорения моей программы, и есть загадка, которую я не могу решить. Я использую multiprocessing, чтобы написать много коротких файлов (на основе большого количества входных файлов) с помощью функции writing_sub_file, и я, наконец, конкатенирую все эти файлы после окончания всех процессов, используя функцию my_concat. Вот два примера кода. Обратите внимание, что этот код находится в моем файле main .py, но функция my_concat импортируется из другого модуля. Первый из них:enigma using python-multiprocessing связанный с if __name__ == '__main__'

if __name__ == '__main__': 
    pool = Pool(processes=cpu_count()) 
    arg_tuple = (work_path, article_dict, cat_len, date_to, time_period, val_matrix) 
    jobs = [(group, arg_tuple) for group in store_groups] 
    pool.apply_async(writing_sub_file, jobs) 
    pool.close() 
    pool.join() 

my_concat(work_path) 

, который дает много ошибок (сколько есть процессы в бассейне), так как он пытается применить my_concat, прежде чем сделаны все мои процессы (я не даю стек ошибки, так как Очень ясно, что функция my_concat пытается применить, прежде чем все файлы будут записаны процессами пула).

Второй:

if __name__ == '__main__': 
    pool = Pool(processes=cpu_count()) 
    arg_tuple = (work_path, article_dict, cat_len, date_to, time_period, val_matrix) 
    jobs = [(group, arg_tuple) for group in store_groups] 
    pool.apply_async(writing_sub_file, jobs) 
    pool.close() 
    pool.join() 
    my_concat(work_path) 

, который отлично работает.

Может кто-нибудь объяснить мне причину?

ответ

2

Во втором, my_concat(work_path) находится внутри оператора if и поэтому выполняется только в том случае, если скрипт работает как основной скрипт.

В первом, my_concat(work_path) находится за пределами инструкции if. Когда multiprocessing импортирует модуль в новый сеанс Python, он не импортируется как __main__, но под его собственным именем. Поэтому этот оператор запускается почти сразу, в каждом из процессов вашего пула, когда ваш модуль импортируется в этот процесс.

+0

О, я вижу ... Поэтому я должен держать все под именем if = main? Каков наилучший способ дождаться завершения всех процессов, а затем выполнить my_concat? – sweeeeeet

+0

@ user3478208 Да, вам нужно держать все под защитой 'if __name__ == __main __". Похоже, что на самом деле вы не используете «многопроцессорство». Вы отправляете * все * своих заданий на один рабочий процесс, ожидая, что этот процесс завершит обработку всех из них, а затем конкатенирует их в родительском. Это совсем не ускорит работу, это немного замедлит вас из-за накладных IPC, необходимых для отправки всех аргументов 'writing_sub_file' дочернего процесса. Что вы на самом деле пытаетесь сделать? – dano

+0

Я хочу обрабатывать все файлы в своем магазине и преобразовывать их в «обработанный файл» (у меня было бы 100 из них), а затем объединить все обработанные файлы в один. Моя идея состояла в том, чтобы использовать многопроцессорную обработку для обработки всех файлов в моем магазине, а затем ждать, пока они не будут обработаны, затем вернитесь к одному процессу и объедините обработанные файлы в один большой файл, а затем продолжите обработку в одном процессе. Что я должен изменить? – sweeeeeet

Смежные вопросы