1

私は IOCP サーバー (オーバーラップ I/O、4 つのスレッド、、、など) で作業してCreateIoCompletionPortGetQueuedCompletionStatusますWSASend。また、自動リセット イベントを作成し、非同期 I/O 操作ごとにハンドルを OVERLAPPED 構造体に配置しました。

問題は、接続されているすべてのソケットにバッファを適切に送信する方法です。各ソケットは、コンテキスト情報構造のリンクされたリストに格納されます。

以下のアプローチが大丈夫かどうかわかりませんか?

...
DWORD WINAPI WorkerThread() { // 1 of 4 workthread
...
GetQueuedCompletionStatus(...);
...
PPER_SOCKET_CONTEXT  pTmp1, pTmp2;
pTmp1 = g_pCtxtList; // start of linked list with sockets
EnterCriticalSection(&g_CriticalSection);
while( pTmp1 ) 
{  
pTmp2 = pTmp1->pCtxtBack;
         WaitForSingleObject(pTmp1->pIOContext->Overlapped.hEvent,infinite);                
          // if there is any pending wsasend on this socket,wait to completed, so
          // we can post another wsasend using the same overlapped structure
          // and buffer
           WSASend(pTmp1->Socket,...,&(pTmp1->pIOContext->Overlapped), NULL);
       pTmp1 = pTmp2;
 }
LeaveCriticalSection(&g_CriticalSection);
...
}

また、別のスレッドも同時に同じ作業を行おうとするとどうなりますか?
すべてのスレッドで GQCS と待機機能を使用することは良い考えですか? マルチスレッド iocp サーバーのすべてのクライアント
に関する手がかりをいただければ幸いです。 どうもwsasends

4

2 に答える 2

2

マーティンが言うように、これはひどく実行され、すべての接続への送信の全期間にわたってロックするソケットのリストを使用するすべてのパフォーマンスを損なう可能性があります. これが UDP なのか TCP なのかはわかりませんが、TCP の場合は、低速のクライアント接続での TCP フロー制御により書き込みの完了が遅れる可能性があるため、サーバーのパフォーマンスの制御をクライアントに渡していることに注意してください ( here )-そして、イベントをトリガーするために書き込み完了を使用していると思いますか?

実際の要件は、メモリの制約のため、またはメモリ コピーをプロファイリングして高価であることがわかったため、サーバー上のデータをコピーして接続ごとに 1 つずつ複数のバッファを割り当てることを避けたいことだと思います。

これに対処する方法は、単一の参照カウント バッファーと、単一のデータ バッファーを参照し、必要な WSABUF を提供するわずかに拡張されたオーバーラップ構造である「バッファー ハンドル」を用意することです。次に、一意の「バッファ ハンドル」を使用して、各接続に「ファイア アンド フォーゲット」書き込みを発行できます。これらはすべて、単一の基礎となるバッファを参照します。すべての書き込みが完了すると、バッファーの ref カウントがゼロになり、クリーンアップされます。Martin が言うように、クリーンアップは、後で再利用するためにバッファーをプールに入れることで実現するのが最善です。

注:あなたがやろうとしていることを実際に理解しているかどうかはわかりません(そのため、最初は回答を削除しました)。フォローしていない場合はお知らせください。調整します...

于 2013-11-04T09:15:04.257 に答える