是否可以按顺序启动池进程?

WoJ*_*WoJ 5 python multiprocessing

下面的代码启动了三个进程,它们在一个池中处理 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()
Run Code Online (Sandbox Code Playgroud)

有没有办法按顺序启动进程(而不是让它们同时启动),并在每个进程启动之间插入延迟?

如果不使用Pool我会multiprocessing.Process(target=worker, args=(nr,)).start()在循环中使用的,则一个接一个地启动它们并根据需要插入延迟。不过,我发现Pool它非常有用(连同map电话),所以如果可能的话,我很乐意保留它。

Vel*_*ker 5

根据文档,不存在对池进程的此类控制。但是,您可以用锁来模拟它:

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()
Run Code Online (Sandbox Code Playgroud)

您的 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()
Run Code Online (Sandbox Code Playgroud)