13

デザインに問題があります:

ハートビート/制御スレッドとメッセージハンドラスレッドの2つのスレッドがあります。

両方が同じソケットを共有していますが、messageHandlerスレッドはメッセージを送信するだけで、受信することはありません。ハートビートスレッドは送受信します(メッセージを受信し、ハートビートに反応します)。

問題は、これが安全かどうかわからないことです。私自身、ソケットが使用されているかどうかを確認するためのメカニズムは実装されていません。では、Pythonでソケットを共有すると、自動的にスレッドセーフになるのでしょうか。

そうでない場合も、別のスレッドに配置する理由は、メッセージ処理よりもハートビートの方が重要だからです。これは、メッセージが殺到した場合でも、ハートビートを実行する必要があることを意味します。したがって、ボルトを実装する必要がある場合、ハートビート/制御スレッドがハートビートを送信する必要があるかどうかを優先することができますか?

4

4 に答える 4

20

3番目のスレッドを使用する代わりに、を使用threading.Lock()してソケットリソースを保護することをお勧めします。これにより、3番目のスレッドが不要になります。3番目のスレッドがある場合よりも、オーバーヘッドとレイテンシーが低くなります。

import threading

lock = threading.Lock()

def sendfunction(sock, data):
    with lock:
        sock.send(data)

どちらのスレッドからでも呼び出すことができますが、一度に呼び出すことができるのは1つのスレッドだけsock.sendです。スレッドが別のスレッドによってすでにロックされているロックに到達すると、他のスレッドがロックを解放するまでスリープし、その後ロックを取得してプロセスが繰り返されます。

スレッドモジュールには、、が含まれていますLockRLockこれらConditionはすべて、複数のスレッドを処理するときに非常に役立ちます。これらのスレッドとその使用法に慣れておく価値は十分にあります。

各メッセージを処理する前に、現在の時刻と最後にハートビートを送信した時刻を確認することで、ハートビートをメッセージ処理に組み込むことができます。これにより、メッセージが殺到してハートビートが送信されなくなるのを防ぐことができます。問題は、メッセージ処理コードが実行されない場合、ハートビートが送信されないことです。メッセージ処理コードに定期的にダミーメッセージを取得させて、ハートビートを送信する必要があるかどうかを確認し、ダミーメッセージを無視することで、これを軽減できます。

スレッドは慎重に使用するようにしてください(単一のスレッドを目指してください)。ただし、ほとんどの時間をスリープ状態にするため、スレッドは問題ない可能性があります。ただし、デーモンスレッドは適切にシャットダウンされないため、使用しないでください。適切にシャットダウンしなかった場合、損傷は存在しない可能性がありますが、それでも何らかの障害(エラーメッセージ)がスローされ、見栄えが悪くなる可能性があります。

実際には状況が複雑になると思うので、マルチソケット方式には同意しません。ハートビートとメッセージを単一のソケットバイトストリームに組み込む多くの種類のネットワークサービス/アプリケーションがあります。

于 2014-09-27T02:49:47.580 に答える
9

残念ながら、マルチスレッドで共有されるソケットはスレッドセーフではありません。2つのスレッドがロックなしで動作するバッファについて考えてみてください。

実装する通常の方法は、ftpのdoes.cmdソケットとmsgソケットと同じように、2つのソケットを使用することです。

これを1つのソケットで実装する場合は、さまざまなタイプのメッセージをさまざまなキューに入れることができ、3番目のスレッドでキューを消費し、それらを唯一のソケットに送信します。

このようにして、データメッセージの前にハートビートメッセージを制御できます。

于 2012-06-24T11:59:19.627 に答える
0

Pythonレベルで優先順位を付ける方法がわかりません。

したがって、スレッドではなく2つのプロセスを使用し、OSレベルで優先順位を付けることをお勧めします。Unixでは、os.nice()を使用してこれを行うことができます。

その場合、2つのソケットを使用する必要があり、共有の問題は同時に解決されます。

于 2012-06-24T11:28:26.787 に答える
0

両方のスレッドがクライアントスレッドである場合は、2つのクライアントソケットを開いて、1つはハートビート用に、もう1つは通信用にサーバーに接続することをお勧めします。

于 2012-06-24T11:39:15.277 に答える