Python3:如何启动2个进程从最先完成的进程返回答案,并提前停止另一个进程

Python3:如何启动2个进程从最先完成的进程返回答案,并提前停止另一个进程,python,python-3.x,asynchronous,concurrency,multiprocess,Python,Python 3.x,Asynchronous,Concurrency,Multiprocess,我有两个算法A和B。两个算法都将相同的字符串作为输入,对字符串执行相同的转换,然后返回一个新字符串 执行的转换有时会占用大量CPU,并且算法对该问题有不同的处理方法。根据输入字符串的不同,算法的性能有很大的不同,但我只关心答案,而不关心哪个算法应用了转换 我编写了一些Psuedo代码来更好地解释这个问题: def process_alg1(algorithm1, input_string) ans_string = algorithm1(input_string) q.put

我有两个算法A和B。两个算法都将相同的字符串作为输入,对字符串执行相同的转换,然后返回一个新字符串

执行的转换有时会占用大量CPU,并且算法对该问题有不同的处理方法。根据输入字符串的不同,算法的性能有很大的不同,但我只关心答案,而不关心哪个算法应用了转换

我编写了一些Psuedo代码来更好地解释这个问题:

def process_alg1(algorithm1, input_string)

    ans_string = algorithm1(input_string)

    q.put(ans_string)

def process_alg2(algorithm2, input_string)

    ans_string = algorithm2(input_string)

    q.put(ans_string)


def apply_transformation(input_string):

    q = multiprocess.Queue()

    process_alg1(input_string)

    process_alg2(input_string)

    final_answer = q.get()

    stop(slowest_process)
我猜我需要使用守护进程?我只是不确定我需要采取什么样的方法。我是否在进程和某种处理器之间设置了一条管道,告诉较慢的进程停止?我可以简单地使用守护进程和队列来实现这一点吗

我已经找到了很多关于同一算法的多个输入的例子,但是没有关于使用同一输入的多个算法的例子


谢谢。

希望这有帮助。使用管道而不是队列:

def process_alg1(algorithm1, input_string)

    ans_string = algorithm1(input_string)

    q.put(ans_string)

def process_alg2(algorithm2, input_string)

    ans_string = algorithm2(input_string)

    q.put(ans_string)


def apply_transformation(input_string):

    q = multiprocess.Queue()

    p1 = process_alg1(input_string)

    p2 = process_alg2(input_string)

    p1.start()
    p2.start()

    while p1.is_alive() and p2.is_alive():
        print 'Both are still computing' 


    final_answer = q.get()

    stop(p1 if p1.is_alive() else p2)

下面是一个简单的例子:

import multiprocessing as mp
from time import sleep
from numpy.random import randint

def task(n, stopsignal):
    for x in range(n): #complex computation task steps (iterations, etc.. however you break it up)
        with stopsignal.getlock():
            if stopsignal.value: 
                print( mp.current_process().name + " recieved stop signal. Terminating.")
        time.sleep(1) #complex computation
    print( mp.current_process().name + " returned first. attempting to halt others..." )

stopsignal = mp.Value('b', 0, lock=True) #'b' for signed 8 bit int (could use other types)
processes = []
for i in range(5): #start 5 processes
    p = Process(
            target=task, 
            name="Process_{}".format(i), 
            args=(randint(5,20),stopsignal,),
        )
    p.start()
    processes.append(p)

while True:
    with stopsignal.getlock():
        if stopsignal.value:
            break
    for p in processes: #check each process
        if p.exitcode is not None: #will be None until process terminates
            with stopsignal.getlock(): #aquire rlock
                stopsignal.value = 1
            break
    sleep(1) #only check every second

您需要主进程定期轮询子进程“
exitcode
属性,以确定它是否已终止。然后,您必须修改其他子级(或两者)定期检查的某种共享变量,以便他们知道退出。发送sigkill不好,也没有直接的windows等价物。@Aaron,如果我对两者都使用守护进程,并从程序的另一部分调用这个apply_转换函数,那么这些进程会在apply_转换调用后终止还是在整个程序完成后终止?没有dameon进程。。“另外,这些不是Unix守护进程或服务,它们是正常的进程”而且我错过了3.x,所以我的坏(3.3中的新功能)。。我仍然不相信这一点,因为[它的工作原理]依赖于平台,windows在僵尸进程方面总是有问题。啊,这真的很简单,我喜欢它。你说用管道代替队列到底是什么意思?在伪代码中,看起来您仍在使用队列。我应该换掉吗?这个答案是不完整的,不会像问题描述的那样停止子进程。进程没有
stop()
函数。最接近这一点的方法是查找pid并使用pcall来杀死它。windows没有真正的等价物。python的多处理模块中有terminate方法可以终止进程。它还返回sigal.SIGTERM