2017-10-13 4 views
0

2つのアルゴリズム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を送信するのはうれしくないし、同等の窓を持たない。 – 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を検索し、それをsigkillするためにpcallを使うことでしょう。窓には実際の均等物はありません。 – Aaron

+0

プロセスを終了できるpythonのマルチプロセッシングモジュールにterminateメソッドがあります。また、それは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
関連する問題