以下代码启动三个进程,它们位于池中以处理20个工作程序调用:
import multiprocessing
def worker(nr):
print(nr)
numbers = [i for i in range(20)]
if __name__ == '__main__':
multiprocessing.freeze_support()
pool = multiprocessing.Pool(processes=3)
results = pool.map(worker, numbers)
pool.close()
pool.join()
有没有办法在序列中启动进程(而不是让它们同时启动),并在每个进程启动之间插入延迟?
如果不使用Pool
,我会在循环中使用multiprocessing.Process(target=worker, args=(nr,)).start()
,一个接一个地启动它们并根据需要插入延迟。我发现Pool
非常有用(与map
调用一起),所以如果可能的话,我很乐意保留它。
答案 0 :(得分:2)
根据documentation,不存在对池化过程的这种控制。但是,你可以用锁来模拟它:
import multiprocessing
import time
lock = multiprocessing.Lock()
def worker(nr):
lock.acquire()
time.sleep(0.100)
lock.release()
print(nr)
numbers = [i for i in range(20)]
if __name__ == '__main__':
multiprocessing.freeze_support()
pool = multiprocessing.Pool(processes=3)
results = pool.map(worker, numbers)
pool.close()
pool.join()
您的3个进程仍将同时启动。好吧,我的意思是你无法控制哪个进程首先开始执行回调。但至少你得到了延迟。这有效地让每个工人开始" (但实际上,继续)按指定的时间间隔。
以下讨论产生的修改:
请注意,在 Windows 上,无法从父进程继承锁定。相反,您可以使用multiprocessing.Manager().Lock()
在进程之间传递全局锁定对象(当然还有额外的IPC开销)。全局锁定对象也需要在每个进程中初始化。这看起来像是:
from multiprocessing import Process, freeze_support
import multiprocessing
import time
from datetime import datetime as dt
def worker(nr):
glock.acquire()
print('started job: {} at {}'.format(nr, dt.now()))
time.sleep(1)
glock.release()
print('ended job: {} at {}'.format(nr, dt.now()))
numbers = [i for i in range(6)]
def init(lock):
global glock
glock = lock
if __name__ == '__main__':
multiprocessing.freeze_support()
lock = multiprocessing.Manager().Lock()
pool = multiprocessing.Pool(processes=3, initializer=init, initargs=(lock,))
results = pool.map(worker, numbers)
pool.close()
pool.join()
答案 1 :(得分:0)
Couldn't you do something simple like this:
from multiprocessing import Process
from time import sleep
def f(n):
print 'started job: '+str(n)
sleep(3)
print 'ended job: '+str(n)
if __name__ == '__main__':
for i in range(0,100):
p = Process(target=f, args=(i,))
p.start()
sleep(1)
Result
started job: 0
started job: 1
started job: 2
ended job: 0
started job: 3
ended job: 1
started job: 4
ended job: 2
started job: 5
答案 2 :(得分:0)
你能尝试定义一个慢慢产生价值的函数吗?
def get_numbers_on_delay(numbers, delay):
for i in numbers:
yield i
time.sleep(delay)
然后:
results = pool.map(worker, get_numbers_on_delay(numbers, 5))
我没有测试过,所以我不确定,但试一试。
答案 3 :(得分:0)
由于某些原因,我无法获得锁定答案,所以我以这种方式实现了它。 我意识到问题是陈旧的,但也许其他人也有同样的问题。
它产生类似于锁定解决方案的所有进程,但在工作之前根据进程名称编号休眠。
from multiprocessing import current_process
from re import search
from time import sleep
def worker():
process_number = search('\d+', current_process().name).group()
time_between_workers = 5
sleep(time_between_workers * int(process_number))
#do your work here
由于给进程的名称似乎是唯一的和增量的,因此根据它来获取进程和休眠的数量。 SpawnPoolWorker-1睡1 * 5秒,SpawnPoolWorker-2睡2 * 5秒等。