1

探しても探しても答えが見つからない。2 つの UNIX デバイス間で Pyro 接続を開こうとしています。同じ URI 文字列を持つ Pyro4 Proxy を使用して、デバイスに 4 回接続できます。5 回目の接続で、インスタンスが get data 関数呼び出しでハングします。core.py pyro パッケージを通過し、最終的にデータを取得するのを待ちます。非常にまれに、4 つ目の接続の後に作成されたこれらの開いている接続の 1 つが、次のような ConnectionClosedError 例外をスローすることがあります。

 ConnectionClosedError("receiving: connection lost: "+str(x))
 ConnectionClosedError: receiving: connection lost: [Errno 104] Connection reset by peer

この問題の原因は次のとおりです: -デバイスへの異なる SSH セッションで 4 つの接続を開き、Pyro プロキシをセットアップするテストを繰り返し実行します。(これらは問題なく動作し、エラーなしで完了します) - より多くの接続を開き、データを取得するための呼び出しにすべてハングします。それらは少なくとも 5 分間ハングし、まれに上記の例外を発生させるものもあります。-全員がそうするわけではありません。実行中の 4 つのテストのうち 1 つが終了すると、ハングしていた 5 番目のテストが開始され、正常に終了します。他の人が続きますが、一度に 4 つを超えることはありません。

最後に、次のコード (socketutil.py 内) で、実際に例外が発生しています。

def receiveData(sock, size):
    """Retrieve a given number of bytes from a socket.
    It is expected the socket is able to supply that number of bytes.
    If it isn't, an exception is raised (you will not get a zero length result
    or a result that is smaller than what you asked for). The partial data that
    has been received however is stored in the 'partialData' attribute of
    the exception object."""
    try:
        retrydelay=0.0
        msglen=0
        chunks=[]
        if hasattr(socket, "MSG_WAITALL"):
            # waitall is very convenient and if a socket error occurs,
            # we can assume the receive has failed. No need for a loop,
            # unless it is a retryable error.
            # Some systems have an erratic MSG_WAITALL and sometimes still return
            # less bytes than asked. In that case, we drop down into the normal
            # receive loop to finish the task.
           while True:
            try:
                data=sock.recv(size, socket.MSG_WAITALL)
                if len(data)==size:
                    return data
                # less data than asked, drop down into normal receive loop to finish
                msglen=len(data)
                chunks=[data]
                break
            except socket.timeout:
                raise TimeoutError("receiving: timeout")
            except socket.error:
                x=sys.exc_info()[1]
                err=getattr(x, "errno", x.args[0])
                if err not in ERRNO_RETRIES:
                    ################HERE:###############
                    raise ConnectionClosedError("receiving: connection lost: "+str(x))
                time.sleep(0.00001+retrydelay)  # a slight delay to wait before retrying
                retrydelay=__nextRetrydelay(retrydelay)

ここで何らかの指示をいただければ幸いです。前もって感謝します!

4

1 に答える 1

0

サーバーが起動時に作成していたスレッドの最小数であることがわかりました。何らかの理由で、必要なときにそれ以上追加されません。

于 2013-03-14T03:32:14.437 に答える