を呼び出すと、プールからの信号を受信しない限り、timeout
に達するまで待機します。ただし、kill -9 [pid]
を実行すると、プールはすぐにキュー内の次のジョブを開始します。
このように、それを利用して手動で "ポーリング"してready()
をチェックする方が簡単です。あなたが述べたように、ジョブが終了すると、ready()
はFalse
のままです。
これを修正するには、pidが有効かどうかを確認します。 ApplyResult
にはpidが含まれていないので、取得するには他の手段が必要です。
def test(identifier):
pid = os.getpid()
f = open("pids/" + str(pid), "w")
f.write(str(identifier))
f.close()
# do stuff
time.sleep(1000)
次に、この(がjobs = []
を考慮)のようなジョブを作成する:あなたはこのような何かを行うことができます。
job = (identifier, pool.apply_async(test, (identifier,)))
jobs.append(job)
識別子が必要しかし、あなたは後でApplyResult
がどのPIDに属するかを把握したい場合に便利ですされていません。各PID-という名前のファイルの内容を考慮し
def is_alive(pid):
return os.path.exists("/proc/" + str(pid))
for pid in os.listdir("pids"):
if is_alive(pid):
...
else:
...
:
各ジョブ(PID)が生きている場合は、すべてのジョブを取得し、確認することができます。次にidentifier
をjobs
に見つけたら、ApplyResult
がどのpidに属しているかをリンクして、特定のジョブが死んでいるかどうかを確認したり、ready()
をチェックしたりすることができます。
パイプを作成して子プロセスをフォークすることもできます。
r, w = os.pipe()
def child():
global r, w
data = ...
time.sleep(100)
os.close(r)
w = os.fdopen(w, "w")
w.write(data)
w.close()
次に、親プロセスにデータを書き戻します。
def parent(child_pid):
global r, w
os.close(w)
r = os.fdopen(r)
data = r.read()
r.close()
status = os.waitpid(child_pid, 0)
if status == 0:
# Everything is fine
elif status == 9:
# kill -9 [pid]
# Process data
その後、status
とdata
は子プロセスに何が起こったのかを判断するために、受信し利用することができます。
あなたはすべてを始めて起動します。あなたの質問から
if __name__ == "__main__":
child_pid = os.fork()
if child_pid:
parent(child_pid)
else:
child()
私は、Unixを想定しています。もし私を修正する気にしないでください。また、非Python 2.7が答えに潜入した場合、私は謝罪します。
https://github.com/noxdafox/pebble - あなたはライブラリを書いたと思いますか? –
はい、私はしました。タイムアウトやクラッシュを処理できる実装がないため、プールがライブラリに追加されました。限られた時間しか保証されないCPU集約型アプリケーションを実行する場合、これは特に重要です。その他のユースケースの例は、アプリケーション全体をクラッシュさせるランダムなsegfaultsを持つCライブラリのPythonバインディングです。 – noxdafox