简体   繁体   English

如何并行启动功能,检查是否完成,并在python中启动一个新的function?

[英]How to start functions in parallel, check if they are done, and start a new function in python?

I want to write a python code that does the following:我想编写一个执行以下操作的 python 代码:

  • At first, it starts, say, 3 processes (or threads, or whatever) in parallel.起初,它会并行启动 3 个进程(或线程或其他)。
  • Then in a loop, python waits until any of the processes have finished (and returned some value)然后在一个循环中,python 等待任何进程完成(并返回一些值)
  • Then, the python code starts a new function然后,python 代码开始一个新的 function

In the end, I want 3 processes always running in parallel, until all functions I need to run are run.最后,我希望 3 个进程始终并行运行,直到我需要运行的所有功能都运行。 Here is some pseudocode:这是一些伪代码:

import time
import random
from multiprocessing import Process

# some random function which can have different execution time
def foo():
    time.sleep(random.randint(10) + 2)
    return 42

# Start 3 functions
p = []
p.append(Process(target=foo))
p.append(Process(target=foo))
p.append(Process(target=foo))

while(True):
    
    # wait until one of the processes has finished
    ???

    # then add a new process so that always 3 are running in parallel
    p.append(Process(target=foo))

I am pretty sure it is not clear what I want.我很确定不清楚我想要什么。 Please ask.请问。

What you really want is to start three processes and feed a queue with jobs that you want executed.您真正想要的是启动三个进程并为队列提供您想要执行的作业。 Then there will only ever be three processes and when one is finished, it reads the next item from the queue and executes that:然后只会有三个进程,当一个完成时,它会从队列中读取下一个项目并执行:

import time
import random
from multiprocessing import Process, Queue

# some random function which can have different execution time
def foo(a):
    print('foo', a)
    time.sleep(random.randint(1, 10) + 2)
    print(a)
    return 42

def readQueue(q):
    while True:
        item = q.get()
        if item:
            f,*args = item
            f(*args)
        else:
            return
    
if __name__ == '__main__':
    q = Queue()
    for a in range(4):  # create 4 jobs
        q.put((foo, a))
    for _ in range(3):  # sentinel for 3 processes
        q.put(None)

    # Start 3 processes
    p = []
    p.append(Process(target=readQueue, args=(q,)))
    p.append(Process(target=readQueue, args=(q,)))
    p.append(Process(target=readQueue, args=(q,)))

    for j in p:
        j.start()
    #time.sleep(10)
    for j in p:
        j.join()

You can use the Pool of the multiprocessing module.您可以使用多处理模块的Pool

my_foos = [foo, foo, foo, foo]

def do_something(method):
     method()


from multiprocessing import Pool
with Pool(3) as p:
    p.map(do_something, my_foos)

The number 3 states the number of parallel jobs.数字 3 表示并行作业的数量。 map takes the inputs as arguments to the function do_something In your case do_something can be a function which calls the functions you want to be processed, which are passed as a list to inputs. map takes the inputs as arguments to the function do_something In your case do_something can be a function which calls the functions you want to be processed, which are passed as a list to inputs.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM