1

Cでwin32を使用して、親スレッド内に不明な数の子スレッドを作成し、それぞれを1つずつ待機するにはどうすればよいですか?
親スレッドの寿命は無限であり、リクエストを待機し、リクエストを受信した場合は、そのリクエストに対して新しい子スレッドを作成します。たとえば、サーバーなどです。
Web を検索していますが、何も見つかりません。
チュートリアルと情報をいただければ幸いです。
どうもありがとう、頑張ってください。

ノート :

1. たとえば、単純なサーバーを想像してみてください。ユーザーがそのサーバーにリクエストを送信すると、サーバーはそのユーザー用に新しいスレッドを作成し、そのスレッドが終了するのを待ちますが、別のユーザーが別のリクエストを送信すると、サーバーは別のスレッドを作成します。古いスレッドが終了すると、サーバーは古いスレッドとは別の新しいスレッドが終了するまで待機する必要があります。

2. メインスレッドは、無限ループで定数 n のサイズでグローバル配列をスキャンし、配列の各ブロックで特定の値を見つけた場合、新しいスレッドを実行してそのブロックの情報に対して何らかの操作を実行し、スレッドが終了した後に更新を終了します。ブロックの情報 . 無限ループがあるため、親スレッドの寿命は無限です。

4

2 に答える 2

1

各スレッドを作成しCreateThread、スレッド ハンドルを動的リストまたは配列に格納します。スレッドがいつ終了したかをメイン スレッドに認識させたい場合は、 を呼び出しWaitForMultipleObjectsて、すべてのスレッド ハンドルを含む配列を提供します。の戻り値は、WaitForMultipleObjectsどのスレッド ハンドルが通知されたか、つまりどのスレッドが終了したかを示します。CloseHandle最後にスレッドハンドルを忘れないでください。

スレッドを生成したいだけで、スレッドがいつ終了するかをメイン スレッドが知る必要がない場合はCreateThread、スレッド ハンドルを使用してスレッドを作成し、閉じることができます。スレッドが終了すると、スレッドのリソースは解放されます。

メイン スレッドでは、クライアント リクエストを受信したかどうかも確認する必要があります。イベントを待機できるクライアントへのインターフェイスがある場合は、 に渡されたイベント配列にイベントを追加するだけWaitForMultipleObjectsです。ケース 2 のようなイベントがない場合はWaitForMultipleObjects、タイムアウトを指定して呼び出すことを検討してくださいWaitForMultipleObjects。スレッドが終了したとき、またはタイムアウトが発生したときに返されます。どちらの場合も、メイン ループは実行され続け、別のスレッドを生成する必要があるかどうかを確認できます。

クライアント要求にイベントを使用する場合の疑似コードを次に示します。

initialize empty list of thread data (thread handles and other data for each thread);
for(;;) {
    create an array a big enough for the request event and for all thread handles;
    a[0] = request event handle;
    a[1..n] = thread handles from the list;
    DWORD ret = WaitForMultiObjects(n+1, a, FALSE, INFINITE);
    if(ret == WAIT_OBJECT_0) {
        create thread and store it's handle and other data in the list;
    }
    else if(WAIT_OBJECT_0 + 1 <= ret  &&  ret <= WAIT_OBJECT_0 + n) {
        thread (ret - WAIT_OBJECT_0 - 1) terminated, do your cleanup and don't forget CloseHandle();
    }
    else
        error occured, should not happen;
}

クライアント リクエストのイベントがない場合は、次のようにポーリングする必要があります。

initialize empty list of thread data (thread handles and other data for each thread);
for(;;) {
    create an array a big enough for the request event and for all thread handles;
    a[0..n-1] = thread handles from the list;
    DWORD ret = WaitForMultiObjects(n, a, FALSE, your desired timeout);
    if(ret != WAIT_TIMEOUT)
        ; // timeout occured, no thread terminated yet, nothing to do here
    else if(WAIT_OBJECT_0 <= ret  &&  ret < WAIT_OBJECT_0 + n) {
        thread (ret - WAIT_OBJECT_0) terminated, do your cleanup and don't forget CloseHandle();
    }
    else
        error occured, should not happen;
    // Always check for client requests, not only in case of WAIT_TIMEOUT.
    // Otherwise you might run into the situation that every time you call WaitForMultiObjects a thread ended just before the timeout occured and you only recognize it after a lot of loop runs when the last thread terminated.
    if(there is a client request) {
        create thread and store it's handle and other data in the list;
    }
}

スレッドごとに余分なデータを保存する必要がない場合は、スレッド ハンドルを保存するだけでよく、既に大きな配列に保存されている可能性があります。したがって、スレッド ハンドル リストから配列を作成する手順を省略できます。

于 2013-04-18T09:21:11.190 に答える