#python #python-3.x #multiprocessing
#python #python-3.x #многопроцессорная обработка
Вопрос:
эй, я пытаюсь ускорить свой код, используя пул многопроцессорных процессов, и теоретически это:
def render_frame(i):
#os.system(f'python main.py video_imgs/out{i}.png {convo}')
print(f'done {i}')
if __name__ == '__main__':
pic_list = list(range(1,num_of_pics))
with Pool(10) as p:
s = p.map(render_frame,pic_list)
затем должно быть напечатано число i, но когда я запускаю скрипт, он просто выдает мне приглашение ввода, которое у меня есть в начале скрипта 10 раз, а именно ->
from multiprocessing import Pool
import sys
import os
import time
if(len(sys.argv) > 1):
vidLoc = sys.argv[1]
convo = sys.argv[2]
else:
vidLoc = input('video: ') #! <-- this is being repeated 10 times
convo = input('convolute cfg file: ')
любая помощь? Спасибо
Комментарии:
1. Вызов os.system() прокомментирован в предоставленном вами коде. Вы уверены, что предоставили правильный фрагмент кода?
2. @ThiagoF. Pappacena да, это правильный фрагмент, который я тестировал и проверял, была ли это проблема, но безрезультатно
3. Если вы нажимаете на другую часть в main.py , это означает, что, вероятно, из этой строки ему не было передано никаких аргументов:
#os.system(f'python main.py video_imgs/out{i}.png {convo}')
<- что{convo}
в этом?
Ответ №1:
В системах, которые используют 'spawn'
в качестве multiprocessing
метода запуска по умолчанию (Windows, macOS), вы должны охранять все «основные скриптовые» поведения под if __name__ == '__main__':
защитой. 'spawn'
Метод имитирует a fork
путем импорта основного модуля в каждый дочерний процесс, но без __main__
имени; если вы выполняете такие вещи, как вызов input
вне guard, он будет выполняться в ваших дочерних процессах. Как правило, вы должны придерживаться простого импорта и определений функций / классов / констант вне защиты, никогда не делайте ничего «активного», если вы не находитесь под охраной (например, избегайте вызова функций с наблюдаемыми побочными эффектами, такими как input
).
Защитите input
код должным образом (вы можете просто опустить его, поскольку странно разрешать необязательные аргументы командной строки, которые вы запрашиваете в противном случае, и раздражает, что они отражены в дочерних процессах), и если вы должны использовать input
, найдите другие способы инициализации переменных в дочернем процессе (например, с помощьюсредства initializer
функции с initargs
, оба являются необязательными аргументами для Pool
).
Грубый пример (ваш неполный код затрудняет точное сопоставление):
from multiprocessing import Pool
import sys
import os
import time
def render_frame(i):
#os.system(f'python main.py video_imgs/out{i}.png {convo}')
print(f'done {i}')
def set_globals(v, c):
global vidLoc, convo
vidLoc = v
convo = c
if __name__ == '__main__':
if len(sys.argv) > 1:
vidLoc = sys.argv[1]
convo = sys.argv[2]
else:
vidLoc = input('video: ') #! <-- this is being repeated 10 times
convo = input('convolute cfg file: ')
pic_list = list(range(1,num_of_pics))
with Pool(10, initializer=set_globals, initargs=(vidLoc, convo)) as p:
s = p.map(render_frame,pic_list)