2017-10-13 23 views
0

我有两个算法A和B.两个算法采用相同的字符串作为输入,执行相同的转换字符串,并返回一个新的字符串。Python 3:我如何开始2个进程返回从哪个结束第一个答案,并提前停止其他进程

执行的转换有时会非常耗费CPU时间,而且算法对这个问题有不同的方法。这些算法根据输入的字符串表现出很大的不同,但我只关心答案,而不是哪种算法适用于转换。

我已经写了一些代码的伪问题的解释好一点:

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) 

我猜我需要使用的守护进程?我只是不确定我需要采取什么方法。我是否在进程和某种处理程序之间建立了一条管道,以便让较慢的进程停止?我可以简单地使用守护进程和队列来做到这一点吗?

我发现了很多用于同一算法的多个输入的例子,但没有多个算法使用相同输入的例子。

谢谢。

+0

你需要的主要过程定期轮询子进程'exitcode'属性,以确定其是否已结束呢。那么你将不得不修改其他孩子(或两者)定期检查的某种共享变量,以便他们知道退出。发送sigkill并不好,并且没有直接的Windows平等。 – Aaron

+0

@Aaron,如果我为两者使用守护进程,并且从我的程序的另一部分调用apply_transformation函数,那么进程会在apply_transformation调用之后或整个程序完成后终止? –

+0

有没有这样的事情作为一个达蒙进程..只有线程 – Aaron

回答

0

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

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) 
+0

啊,这真的很简单,我喜欢它。你究竟用管道代替队列是什么意思?在伪代码中,它看起来像你还在使用队列。我应该换掉吗? –

+0

这个答案是不完整的,不会像描述的问题那样停止子进程。进程没有'stop()'函数。最接近的就是查找pid并使用pcall来发送它。没有真正的Windows相同。 – Aaron

+0

python多处理模块中有终止方法可以终止进程。另外它返回singal.SIGTERM –

1

这里有一个小例子:

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
相关问题