Используйте аргументы initializer и initargs при создании пула, чтобы определить глобальный объект во всех дочерних процессах.
Например:
from multiprocessing import Pool, Lock
from time import sleep
def do_job(i):
"The greater i is, the shorter the function waits before returning."
with lock:
sleep(1-(i/10.))
return i
def init_child(lock_):
global lock
lock = lock_
def main():
lock = Lock()
poolsize = 4
with Pool(poolsize, initializer=init_child, initargs=(lock,)) as pool:
results = pool.imap_unordered(do_job, range(poolsize))
print(list(results))
if __name__ == "__main__":
main()
Этот код выведет числа от 0 до 3 в порядке возрастания (в порядке отправки заданий), потому что он использует блокировку. Закомментируйте строку with lock:
, чтобы она распечатала числа в порядке убывания.
Это решение работает как в Windows, так и в Unix. Однако, поскольку процессы могут разветвляться в системах unix, unix нужно только объявить глобальные переменные в области модуля. Дочерний процесс получает копию памяти родителя, которая включает объект блокировки, который все еще работает. Таким образом, инициализатор не является строго необходимым, но он может помочь документировать работу кода. Когда многопроцессорность может создавать процессы путем разветвления, то также работает следующее.
from multiprocessing import Pool, Lock
from time import sleep
lock = Lock()
def do_job(i):
"The greater i is, the shorter the function waits before returning."
with lock:
sleep(1-(i/10.))
return i
def main():
poolsize = 4
with Pool(poolsize) as pool:
results = pool.imap_unordered(do_job, range(poolsize))
print(list(results))
if __name__ == "__main__":
main()
person
Dunes
schedule
25.02.2015
Lock
илиSemaphore
? Есть ли причина не использовать простоmultiprocessing.Lock
/multiprocessing.Semaphore
? - person dano   schedule 23.02.2015