2016-05-08 12 views
1

私は、マルチプロセッシングライブラリでPython 2.7.11(Windows上)でタイムアウト関数を作成しようとしています。マルチプロセスでのPythonでのタイムアウト関数の作成

基本的な目標は、関数がタイムアウトした場合は1つの値を返し、タイムアウトしない場合は実際の値を返すことです。

私のアプローチは以下の通りです:

from multiprocessing import Process, Manager 

def timeoutFunction(puzzleFileName, timeLimit): 
    manager = Manager() 
    returnVal = manager.list() 

    # Create worker function 
    def solveProblem(return_val): 
    return_val[:] = doSomeWork(puzzleFileName) # doSomeWork() returns list 

    p = Process(target=solveProblem, args=[returnVal]) 
    p.start() 

    p.join(timeLimit) 
    if p.is_alive(): 
    p.terminate() 
    returnVal = ['Timeout'] 

    return returnVal 

そして、私はこのような関数を呼び出す:

if __name__ == '__main__': 
    print timeoutFunction('example.txt', 600) 

残念ながら、これは動作しないと私はpickle.pyでEOFエラーのいくつかの並べ替えを受け取ります

誰かが間違っているのを誰でも見ることができますか?事前に

おかげで、
アレクサンダー

編集: doSomeWork()は、実際の関数ではありません。私がする他の仕事のためのちょうどフィラー。その作業は並行して行われず、共有変数を使用しません。私は単一の関数を実行しようとしているだけで、おそらくタイムアウトにしています。

+0

doSomeWorkとは何ですか? –

+0

ちょうどフィラー機能。私の実際のsolveProblem()はそうではありません。私の問題を単純化しようとしていたのですが、関数の内容がうまくいくので見てください。 –

答えて

1

これにはPebbleライブラリを使用できます。

from pebble import concurrent 
from concurrent.futures import TimeoutError 

TIMEOUT_IN_SECONDS = 10 

@concurrent.process(timeout=TIMEOUT_IN_SECONDS) 
def function(foo, bar=0): 
    return foo + bar 

future = function(1, bar=2) 

try: 
    result = future.result() # blocks until results are ready or timeout 
except TimeoutError as error: 
    print "Function took longer than %d seconds" % error.args[1] 
    result = 'timeout' 

documentationにはさらに完全な例があります。

タイムアウトが発生した場合、ライブラリは機能を終了させるので、浪費されるIOやCPUについて心配する必要はありません。

EDIT:あなたは割り当てをやっている場合は

、あなたはまだits実装を見ることができます。

ショート例:

from multiprocessing import Pipe, Process 

def worker(pipe, function, args, kwargs): 
    try: 
     results = function(*args, **kwargs) 
    except Exception as error: 
     results = error 

    pipe.send(results) 

pipe = Pipe(duplex=False) 
process = Process(target=worker, args=(pipe, function, args, kwargs)) 

if pipe.poll(timeout=5): 
    process.terminate() 
    process.join() 
    results = 'timeout' 
else: 
    results = pipe.recv() 

ペブルは、きちんとしたAPIを提供コーナーケースの世話をし、より堅牢なメカニズムを使用しています。しかし、これは多かれ少なかれボンネットの下で何をしています。

+0

非常にきれい!残念ながらこれは割り当てのためのものなので、私は外部ライブラリを使用しない方がよいでしょう。しかし、私はこれを他のプロジェクトにも留意しています。ありがとう! –

0

問題は、solveProblem関数が外部関数の内部で定義されていたようです。 Pythonはそれを好きではないようです。私はそれを外に移動した後、それは正常に働いた。

私はこの答えに私を導いた小石の解決策を実装するように答えとしてnoxdafoxの答えをマークします。

ありがとうございます!

関連する問題