1

multiprocessing.Poolを使いたいですが、multiprocessing.Poolはタイムアウト後にタスクを中断できません。私はsolutionを見つけ、それを変更しました。Pythonマルチプロセッシングプールのタイムアウト

from multiprocessing import util, Pool, TimeoutError 
from multiprocessing.dummy import Pool as ThreadPool 
import threading 
import sys 
from functools import partial 
import time 


def worker(y): 
    print("worker sleep {} sec, thread: {}".format(y, threading.current_thread())) 
    start = time.time() 
    while True: 
     if time.time() - start >= y: 
      break 
     time.sleep(0.5) 
     # show work progress 
     print(y) 
    return y 


def collect_my_result(result): 
    print("Got result {}".format(result)) 


def abortable_worker(func, *args, **kwargs): 
    timeout = kwargs.get('timeout', None) 
    p = ThreadPool(1) 
    res = p.apply_async(func, args=args) 
    try: 
     # Wait timeout seconds for func to complete. 
     out = res.get(timeout) 
    except TimeoutError: 
     print("Aborting due to timeout {}".format(args[1])) 
     # kill worker itself when get TimeoutError 
     sys.exit(1) 
    else: 
     return out 


def empty_func(): 
    pass 


if __name__ == "__main__": 
    TIMEOUT = 4 
    util.log_to_stderr(util.DEBUG) 
    pool = Pool(processes=4) 

    # k - time to job sleep 
    featureClass = [(k,) for k in range(20, 0, -1)] # list of arguments 
    for f in featureClass: 
     # check available worker 
     pool.apply(empty_func) 

     # run job with timeout 
     abortable_func = partial(abortable_worker, worker, timeout=TIMEOUT) 
     pool.apply_async(abortable_func, args=f, callback=collect_my_result) 

    time.sleep(TIMEOUT) 
    pool.terminate() 
    print("exit") 

主変形 - sys.exit(1)とワーカープロセスの終了。それはワーカープロセスを殺し、ジョブスレッドを殺すことですが、私はこの解決策が良いとは確信していません。プロセスが実行中のジョブで終了すると、どのような潜在的な問題が発生する可能性がありますか?

+0

私はあなたの労働者()のタイムアウトを処理し、結果を共通のコレクションに書き込むほうがよいでしょう。このようにして、すべてのスレッドでjoin()を呼び出し、結果を処理するだけで済みます。システムに負荷がかかっていない場合は、正常に動作するはずです。 – mljli

答えて

4

実行中のジョブを中止する際の暗黙のリスクはなく、OSはプロセスを正しく終了させることに注意します。

ジョブがファイルに書き込んでいる場合は、ディスク上に切り捨てられたファイルがたくさんある可能性があります。

DBに書き込む場合や、リモートプロセスに接続している場合は、小さな問題が発生することがあります。

しかし、Python標準プールはタイムアウトをサポートしておらず、プロセスを突然終了させるとアプリケーション内で奇妙な動作につながる可能性があります。

Pebble処理プールでは、タイムアウトタスクがサポートされています。

from pebble import process, TimeoutError 

with process.Pool() as pool: 
    task = pool.schedule(function, args=[1,2], timeout=5) 

    try: 
     result = task.get() 
    except TimeoutError: 
     print "Task: %s took more than 5 seconds to complete" % task 
+0

いいですね。本番環境で成功例を使用していますか? – rusnasonov

+0

私が正しく理解しているか分かりません。あなたは、生産やシステムの殺害プロセスのペブルの成功の話をしたいですか?ペブルは非常に安定したライブラリであり、公正な[ダウンロード量](http://pypi-ranking.info/module/Pebble)を持っています。 – noxdafox

+0

はい、正しく理解しています。あなたはpeebleを使用してプロジェクトを知っていますか? – rusnasonov

関連する問題