我有一些程序,其中多个进程试图完成某些功能。我现在的目标是在一个进程成功完成该功能后停止所有其他进程。
不幸的是,下面显示的python程序一直等到所有进程都成功地解决了find函数中给出的问题。我该如何解决我的问题?
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())
输出可以是例如:
['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']
但这个输出显示程序正在等待,直到所有进程都完成。。。
使用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上的默认值,但在linux上也可用。在这些系统上,主模块是导入到新创建的Python进程中。这需要在没有副作用的情况下发生,例如启动进程,__name__
机制确保了这一点。
您可以使用multiprocessing.Queue
和multiprocessing.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)
您可能还想研究设置守护进程,它会在主进程退出后杀死进程。