繁体   English   中英

Python:多处理 - 在一个进程完成后终止其他进程

[英]Python: multiprocessing - terminate other processes after one process finished

我有一些程序,其中多个进程尝试完成一些 function。我现在的目标是在一个进程成功完成 function 后停止所有其他进程。

不幸的是,下面显示的 python 程序一直等到所有进程都成功解决了 find function 中给出的问题。我该如何解决我的问题?

import multiprocessing
import random

FIND = 50
MAX_COUNT = 100000
INTERVAL = range(10)

def find(process, initial, return_dict):
    succ = False
    while succ == False:
        start=initial
        while(start <= MAX_COUNT):
            if(FIND == start):
                return_dict[process] = f"Found: {process}, start: {initial}"
                succ = True
                break;
            i = random.choice(INTERVAL)
            start = start + i
            print(start)

processes = []
manager = multiprocessing.Manager()
return_code = manager.dict()
for i in range(5):
    process = multiprocessing.Process(target=find, args=(f'computer_{i}', i, return_code))
    processes.append(process)
    process.start()

for process in processes:
    process.join()


print(return_code.values())

output 可以是例如:

['Found: computer_0, start: 0', 'Found: computer_4, start: 4', 'Found: computer_2, start: 2', 'Found: computer_1, start: 1', 'Found: computer_3, start: 3']

但是这个 output 告诉我程序正在等待所有进程完成......

使用Event来管理进程是否应该继续运行。

基本上,它将succ替换为适用于所有进程的东西。

import multiprocessing
import random

FIND = 50
MAX_COUNT = 1000


def find(process, initial, return_dict, run):
    while run.is_set():
        start = initial
        while start <= MAX_COUNT:
            if FIND == start:
                return_dict[process] = f"Found: {process}, start: {initial}"
                run.clear() # Stop running.
                break
            start += random.randrange(0, 10)
            print(start)


if __name__ == "__main__":
    processes = []
    manager = multiprocessing.Manager()
    return_code = manager.dict()
    run = manager.Event()
    run.set()  # We should keep running.
    for i in range(5):
        process = multiprocessing.Process(
            target=find, args=(f"computer_{i}", i, return_code, run)
        )
        processes.append(process)
        process.start()

    for process in processes:
        process.join()

    print(return_code.values())

请注意,必须使用__name__使多处理在 ms-windows 和 macOS 上正常工作。 在这些系统上,主模块被导入到新创建的 Python 个进程中。 这需要在没有副作用的情况下发生,例如启动进程,而__name__机制确保了这一点。

您可以使用multiprocessing.Queuemultiprocessing.Queue.get执行此操作。 这是如何工作的,默认情况下get阻塞,直到队列中有内容。 因此它将返回第一个附加到队列的结果,即完成搜索的进程之一。 之后,我们可以遍历进程并终止每个进程(请注意,终止进程不会杀死进程产生的子进程,除非daemon设置为 True)。

import multiprocessing
import random
import time 

FIND = 50
MAX_COUNT = 100000
INTERVAL = range(10)

queue = multiprocessing.Queue(maxsize=1)

def find(process, initial):
    succ = False
    while succ == False:
        start=initial
        while(start <= MAX_COUNT):
            if(FIND == start):
                queue.put(f"Found: {process}, start: {initial}")
                break;
            i = random.choice(INTERVAL)
            start = start + i
            print(process, start)

processes = []
manager = multiprocessing.Manager()
for i in range(5):
    process = multiprocessing.Process(target=find, args=(f'computer_{i}', i))
    processes.append(process)
    process.start()

ret = queue.get()
for i in range(5):
    process = processes[i]
    process.terminate()
    print(f'terminated {i}')

print(ret)

您可能还想研究设置 daemon ,它会在主进程退出后终止进程。

暂无
暂无

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

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