15

複雑なシミュレーションのパラメーターの最適化を行っています。最適化アルゴリズムのパフォーマンスを向上させるために multiprocessing モジュールを使用しています。http://pymotw.com/2/multiprocessing/basics.htmlで学んだ multiprocessing の基本。複雑なシミュレーションは、最適化アルゴリズムから与えられたパラメーターに応じて、さまざまな時間 (約 1 ~ 5 分) 続きます。パラメータの選択が非常に悪い場合、シミュレーションは 30 分以上続く可能性があり、結果は役に立ちません。そこで、マルチプロセッシングにタイムアウトを組み込むことを考えていました。これにより、定義された時間以上続くすべてのシミュレーションが終了します。問題の抽象化されたバージョンは次のとおりです。

import numpy as np
import time
import multiprocessing

def worker(num):
    
    time.sleep(np.random.random()*20)

def main():
    
    pnum = 10    
    
    procs = []
    for i in range(pnum):
        p = multiprocessing.Process(target=worker, args=(i,), name = ('process_' + str(i+1)))
        procs.append(p)
        p.start()
        print('starting', p.name)
        
    for p in procs:
        p.join(5)
        print('stopping', p.name)
     
if __name__ == "__main__":
    main()

p.join(5)は 5 秒のタイムアウトを定義します。forループfor p in procs:のため、プログラムは最初のプロセスが終了するまで5秒間待機し、2番目のプロセスが終了するまで5秒間待機しますが、5秒以上続くすべてのプロセスをプログラムに終了させたいです。さらに、どのプロセスも 5 秒以上継続しない場合、プログラムはこの 5 秒間待機してはなりません。

4

3 に答える 3

13

マルチプロセッシングからプールを使用できるすべてのプロセスを強制終了する場合は、個々のタイムアウトではなく、すべての実行に対して一般的なタイムアウトを定義する必要があります。

import numpy as np
import time
from multiprocessing import Pool

def worker(num):
    xtime = np.random.random()*20
    time.sleep(xtime)
    return xtime

def main():

    pnum = 10
    pool = Pool()
    args = range(pnum)
    pool_result = pool.map_async(worker, args)

    # wait 5 minutes for every worker to finish
    pool_result.wait(timeout=300)

    # once the timeout has finished we can try to get the results
    if pool_result.ready():
        print(pool_result.get(timeout=1))

if __name__ == "__main__":
    main()

これにより、すべてのワーカーの戻り値のリストが順番に取得されます。
詳細はこちら: https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.pool

于 2015-03-31T21:08:44.237 に答える
3

dano の助けのおかげで、私は解決策を見つけました:

import numpy as np
import time
import multiprocessing

def worker(num):

    time.sleep(np.random.random()*20)

def main():

    pnum = 10    
    TIMEOUT = 5 
    procs = []
    bool_list = [True]*pnum

    for i in range(pnum):
        p = multiprocessing.Process(target=worker, args=(i,), name = ('process_' + str(i+1)))
        procs.append(p)
        p.start()
        print('starting', p.name)

    start = time.time()
    while time.time() - start <= TIMEOUT:
        for i in range(pnum):
            bool_list[i] = procs[i].is_alive()
            
        print(bool_list)
            
        if np.any(bool_list):  
            time.sleep(.1)  
        else:
            break
    else:
        print("timed out, killing all processes")
        for p in procs:
            p.terminate()
            
    for p in procs:
        print('stopping', p.name,'=', p.is_alive())
        p.join()

if __name__ == "__main__":
    main()

これは最もエレガントな方法ではありません。使用するよりも良い方法があると確信していbool_listます。5 秒のタイムアウト後にまだ生きているプロセスは強制終了されます。ワーカー関数でタイムアウトよりも短い時間を設定している場合、5 秒のタイムアウトに達する前にプログラムが停止することがわかります。ある場合、私はまだよりエレガントなソリューションを受け入れています:)

于 2014-09-27T11:31:34.350 に答える