1

テキスト ファイルを開き、各行をループするスクリプトを作成しています (各行の間に数秒の一時停止があります)。行ごとに、一時的なクライアント ソケット接続を開き、テキストをホスト サーバーに送信します。ホストの応答が来る場合と来ない場合があります。どちらでも構いません。

既存のソケット オブジェクトに再接続できないという Python ソケットの制限に既に遭遇しました (再接続すると例外が発生するためEBADF, 'Bad file descriptor')。そのため、一時的な接続ごとに新しいソケット インスタンスを作成しています。もちろん、秘訣はメモリリークを回避する方法になります。

私がこれにアプローチした方法は、ソケットの作成、使用、およびクローズのすべての部分を関数にプッシュすることです。Python のガベージ コレクションを利用して、処理が終わった後に各インスタンスを削除します。

    ソケットのインポート、選択、時間

    def transientConnect (ホスト、ポート、sendData):
        応答 = ''
        sendSocket = socket.socket()
        sendSocket.connect((serverHost,serverPort))
        sendSocket.send(行)
        gotData = select.select([sendSocket],[],[],2)
        if (gotData[0]):response = sendSocket.recv(65535)
        sendSocket.close()
        応答を返す

    scriptLines = open('testScript.txt','r').readlines()
    サーバーホスト = '127.0.0.1'
    サーバーポート = 15004
    scriptLines の行:
        応答 = transientConnect(serverHost,serverPort,line)
        印刷(応答)
        時間.スリープ(3.0)

私の質問: (1) このアプローチは、メモリ リークを回避するために機能しますか? (2) 終了後に各インスタンスが確実に削除されるようにする、より直接的な方法はありますか?

4

1 に答える 1

4

まず、単一の交換にのみソケットを使用するのが普通です。ソケット HOWTOを参照してください。

Python の優れている点の 1 つは、一般にガベージ コレクションを気にする必要がないことです。実際のメモリ使用に問題がない限り、そうすべきではありません。

この Web ページから、次の点に注意してください。

「オブジェクトがスコープ外に出た場合、Python はそのオブジェクトをクリーンアップしません。オブジェクトへの最後の参照がスコープ外になったときに、オブジェクトをクリーンアップします。」

そのため、関数内で作成されたソケットが他の場所で参照されていない場合は、スコープ外に出て割り当てを解除する必要があります (ただし、gc ではありません)。以下はおそらくcpythonに固有のものです。gc.set_threshold()cpython でガベージ コレクションがどのように機能するかについては、ドキュメントを参照してください。特に:

「割り当て数から割り当て解除数を引いた値がthreshold0を超えると、収集が開始されます。」

しきい値の標準値 (cpython で) は次のとおりです。

In [2]: gc.get_threshold()
Out[2]: (700, 10, 10)

そのため、gc を実行する前にかなりの数の割り当てが必要になります。を実行すると、ガベージ コレクションを強制できますgc.collect()

于 2012-12-29T14:06:18.543 に答える