3

Cでpthreadsを使用してプログラミングしています。

ID 0、1、2、3 の 4 つの子スレッドを作成する必要がある親スレッドがあります。親スレッドがデータを取得すると、データを分割し、それを 4 つの個別のコンテキスト変数 (サブスレッドごとに 1 つ) に割り当てます。 . サブスレッドはこのデータを処理する必要があり、その間、親スレッドはこれらのスレッドで待機する必要があります。これらのサブスレッドの実行が完了すると、対応するコンテキスト変数に出力が設定され、(再利用のために) 待機します。親スレッドは、これらすべてのサブスレッドがこのラウンドを完了したことを認識すると、グローバル出力を計算して出力します。現在、新しいデータを待機しています (サブスレッドはまだ強制終了されておらず、待機しているだけです)。

親スレッドがさらにデータを取得すると、上記のプロセスが繰り返されます - 既に作成された 4 つのスレッドがあります。

親スレッドが kill コマンド (特定の種類のデータを想定) を受信すると、すべてのサブスレッドに通知され、それらは終了します。これで、親スレッドを終了できます。

私は修士課程の研究生で、上記のシナリオの必要性に直面しています。これは、pthread_cond_wait、pthread_Cond_signal を使用して実行できることを知っています。コードを書きましたが、無期限に実行されているだけで、理由がわかりません。

私の推測では、私がコーディングした方法では、シナリオを過度に複雑にしました。これをどのように実装できるかを知ることは非常に役立ちます。必要があれば、コードの簡略版を投稿して、何をしようとしているのかを示すことができます (私のアプローチには欠陥があると思いますが!)...

pthread を使用してこのシナリオを実装する方法について、何か洞察を教えてください。

4

2 に答える 2

1

あなたの説明からわかる限り、原則に問題はないようです。

あなたが実装しようとしているのはワーカープールです。そこには多くの実装があるはずです。スレッドが実行している作業が実質的な計算 (少なくとも CPU 秒程度) である場合、そのようなスキームは完全にやり過ぎです。Mondern の POSIX スレッドの実装は、非常に多くのスレッドの作成をサポートするほど効率的であり、オーバーヘッドは法外なものではありません。

(スレッドの戻り値ではなく) 共有変数、ミューテックスなどを介してワーカーに通信させる場合に重要な唯一のことは、 to 属性パラメーターを使用して、スレッドを切り離して開始することですpthread_create

タスクにそのような実装ができたら、測定します。その後、pthread ルーチンでかなりの時間を費やしていることがプロファイラーから通知された場合にのみ、ワーカー プールを実装 (または使用) してスレッドをリサイクルすることを検討してください。

于 2012-04-20T06:25:47.407 に答える
0

4つのスレッドがぶら下がっている1つの生産者/消費者スレッド。4つのタスクをキューに入れたいスレッドは、他のすべてのデータと同様に、「OnComplete」関数への関数ポインターを含む4つのコンテキスト構造体をアセンブルします。次に、4つのコンテキストすべてをキューに送信し、タスクカウントを4までアトミックにインクリメントし、イベント/条件/セマフォを待機します。

4つのスレッドは、PCキューからコンテキストを取得し、機能します。

完了すると、スレッドは「OnComplete」関数ポインタを呼び出します。

OnCompleteでは、スレッドはtaskCountをアトミックにカウントダウンします。スレッドがそれをゼロにデクリメントする場合、はイベント/ condvar /セマフォを通知し、すべてのタスクが完了したことを認識して、元のスレッドが実行されます。

コンテキストのアセンブリとシンクロ待機がタスクでも実行されるように調整することはそれほど難しくありません。そのため、プールが複数の要求スレッドに対して複数の「ForkAndWait」操作を一度に処理できるようにします。

このような操作は、オブジェクト指向言語では非常に簡単です。たとえば、最新のJavaには「ForkAndWait」スレッドプールクラスがあり、まさにこの種の処理を実行する必要がありますが、C ++(または農奴制に興味がある場合はC#)はプレーンCよりも優れています。

于 2012-04-20T21:46:01.593 に答える