0

私は自分のプロジェクト (C/C++) としてオーディオ ストリーマー (クライアント サーバー) を作成しており、このプロジェクト用にマルチスレッド UDP サーバーを作成することにしました。

この背後にあるロジックは、各クライアントが独自のスレッドで処理されるということです。私が抱えている問題は、スレッド同士の干渉です。

サーバーが最初に行うことは、一種のスレッドプールを作成することです。関数によってすべてが自動的にブロックされる5つのスレッドが作成されますがrecvfrom()、ほとんどの場合、別のデバイスをサーバーに接続すると、複数のスレッドが応答し、後でサーバーが完全にブロックされ、それ以上操作しないでください。

これをデバッグするのもかなり難しいので、マルチスレッド UDP サーバーが通常どのように実装されているかについてアドバイスを得るためにここに書きます。

コードの一部でミューテックスまたはセマフォを使用する必要がありますか? もしそうなら、どこですか?

どんなアイデアでも非常に役に立ちます。

4

4 に答える 4

1

サーバーが最初に行うことは、一種のスレッドプールを作成することです。recvfrom() 関数によってすべてが自動的にブロックされる 5 つのスレッドを作成しますが、ほとんどの場合、別のデバイスをサーバーに接続すると、複数のスレッドが応答し、後でサーバーが完全にブロックされ、それ以上動作しません

すべてのスレッドを同じソケット接続の recvfrom() に配置するのではなく、セマフォで接続を保護し、ワーカー スレッドをセマフォで待機させる必要があります。スレッドがセマフォを取得すると、recvfrom() を呼び出すことができます。それがパケットとともに返されると、スレッドはセマフォを解放して (別のスレッドが取得できるように)、パケット自体を処理できます。パケットの処理が完了すると、セマフォでの待機に戻ることができます。これにより、スレッド間でデータを転送する必要がなくなります。

于 2013-01-02T17:33:58.707 に答える
1

一歩下がって:あなたは言う

各クライアントは独自のスレッドで処理されます

しかし、UDP は接続指向ではありません。すべてのクライアントが同じマルチキャスト アドレスを使用する場合、特定のパケットを処理するスレッドを決定する自然な方法はありません。


各クライアントが独自のスレッドを取得するという考えに執着している場合 (私は一般的に反対しますが、ここでは理にかなっています)、各パケットがどのクライアントから来たのかを特定する方法が必要です。

つまり、どちらか

  • TCPを使用する(とにかく接続指向の動作を試みているように見えるため)
  • 各パケットを読み取り、それが属する論理クライアント接続を特定し、正しいスレッドに送信します。ルーティング情報はグローバル/共有状態であるため、これら 2 つは同等であることに注意してください。

    1. ソース IP を保持 -> スレッド マッピング、ミューテックスで保護、すべてのスレッドからの読み取りとアクセス
    2. すべての読み取りを 1 つのスレッドで実行し、ローカル ソース IP -> スレッド マッピングを使用します

    最初のものはあなたが求めているもののようですが、デザインが貧弱です. パケットが着信すると、1 つのスレッドが起動され、ミューテックスがロックされてルックアップが実行され、別のスレッドが起動される可能性があります。この接続を処理したいスレッドも読み取りがブロックされている可能性があるため、それを起こすための何らかのメカニズムが必要です。

    2 つ目は、少なくとも懸念の分離 (読み取り/ディスパッチと処理) を提供します。


賢明なことに、あなたのデザインはに依存する必要があります

  • クライアント数
  • I/O負荷
  • 非 I/O 処理の量 (または IO:CPU 比率など)
于 2012-12-27T00:30:47.143 に答える
0

あなたの主な問題は、非永続的な udp 接続だと思います。Udp は接続を維持していません。セッションごとに 2 つのデータグラムしか交換しません。アプリケーションによっては、最悪の場合、最初に利用可能な情報から読み取る同時スレッドが発生します。つまり、recvfrom() は、それを行う番でなくてもブロックを解除します。

メインスレッドでselectを使用し、並行バッファを使用して、スレッドが何をするかを管理する方法だと思います。このソリューションでは、クライアントごとに 1 つのスレッド、またはファイルごとに 1 つのスレッドを持つことができます。これは、クライアントが必要な情報を保持して、正しいファイル部分を送信していることを確認することを前提としています。

TCP は、実行するスレッドごとに接続を維持するため、別の方法ですが、データ損失が許可されたアプリケーションでの最適な送信方法ではありません。

于 2012-12-26T23:52:25.673 に答える
0

recvfrom はマスター スレッドにある必要があり、データを取得するときに、アドレス IP:Port と UDP クライアントのデータをヘルパー スレッドに渡す必要があります。

IP:port とデータを渡すには、マスター スレッドが UDP パケットを受信するたびに新しいスレッドを生成するか、メッセージ キューを介してヘルパー スレッドに渡すことができます。

于 2012-12-26T13:54:53.590 に答える