3

4つのノードとマスターサーバーを持つクラスターがあります。マスターは、終了するまでに30秒から15分かかる可能性のあるジョブをディスパッチします。

ノードはでリッスンしてSocketServer.TCPServerおり、マスターで接続を開き、ジョブが終了するのを待ちます。

def run(nodes, args):
    pool = multiprocessing.Pool(len(nodes))
    return pool.map(load_job, zip(nodes, args))

load_job関数はデータを送信し、そのsocket.sendall直後に使用しますsocket.recv(データが到着するまでに長い時間がかかります)。

これらのジョブの約200または300が実行されるまで、プログラムは正常に実行されます。それが壊れると、socket.recvは空の文字列を受け取り、ノードプロセスを強制終了して再度実行するまで、これ以上ジョブを実行できません。

データが来るのをどのように待つ必要がありますか?また、のエラー処理はpool、別のプロセスからのエラーを保存し、適切なトレースバックなしで表示され、このエラーが繰り返されることはあまりないため、非常に貧弱です...


編集:今、私はこの問題はソケットとは何の関係もないと思います:

いくつかの調査の後、私のノードは多くのプロセスへの道を開いているように見えます(それらはでジョブを実行するためmultiprocessing.Pool)そしてどういうわけかそれらは閉じられていません!

私はこれらのSOの質問(ここここ)がデーモン化されたプロセスで使用するときのゾンビプロセスについて話しているのを見つけましmultiprocessingた(まさに私の場合です!)。

問題をさらに理解する必要がありますが、今のところ、ノードを強制終了し、しばらくしてから復元しています。

4

1 に答える 1

3

(私はあなたがそれで何を意味したのか正確に理解していないので、編集の前に質問に答えています)。

socket.recvソケットでデータを待つための最良の方法ではありません。私が知っている最善の方法は、selectモジュールを使用することです(ここにドキュメントがあります)。単一のソケットでデータを待機する場合の最も簡単な使用法はですがselect.select([your_socket],[],[])、より複雑なタスクにも使用できます。

socket.recv空の文字列を受け取る問題について; ソケットがTCPソケットの場合(あなたの場合のように)、これはソケットがピアによって閉じられたことを意味します。この理由はさまざまですが、理解しておくべき重要なことは、これが発生すると、このソケットからデータを受信しなくなるため、ソケットを閉じることです(socket.close)。それが閉じることを期待しない場合は、ここで問題を検索する必要があります。

幸運を!

于 2012-10-10T08:12:59.893 に答える