0

2つのスレッドが必要です。最初の thread1 は、次の疑似関数を時々呼び出します。

void waitForThread2() {
  if (thread2 is not idle) {
    return;
  }
  notifyThread2IamReady(); // i.e. via 1st condition variable
  Wait for thread2 to finish exclusive access. // i.e. via 2nd condition variable.
}

2 番目の thread2 は、次の疑似ループで永遠に続きます。

for (;;) {
  Notify thread1 I am idle.
  Wait for thread1 to be ready. // i.e. via 1st condition variable.
  Notify thread1 I am exclusive.
  Do some work while thread1 is blocked.
  Notify thread1 I am busy. // i.e. via 2nd condition variable.
  Do some work in parallel with thread1.
}

複数のコアを持つマシンでスレッド 1 とスレッド 2 の両方が可能な限りビジー状態に保たれるようにこれを記述する最良の方法は何ですか。あるスレッドでの通知と別のスレッドによる検出との間の長い遅延を避けたいと思います。pthread 条件変数を使用してみましたが、thread2 が 'notify thread1 I am busy' を実行してから、ar2IsExclusive() の waitForThread2() のループまでの遅延が最大で 1 秒近くになることがわかりました。次に、揮発性の sig_atomic_t 共有変数を使用して同じものを制御しようとしましたが、何かがうまくいかないので、正しく実行していないに違いありません。

4

3 に答える 3

3

何らかの条件が発生するのを待ってスレッドをアイドル状態にする「while」ループを使用するのではなく、シグナル伝達にセマフォを使用する必要があるようです。アイドル ループはよくありません。

于 2010-05-25T02:16:25.403 に答える
1

スレッドに「忙しい」または「忙しくない」とお互いに言わせるのではなく、スレッドが操作しているデータ オブジェクトの観点から考えてみてください。

両方のスレッドが同時に変更しようとする可能性のあるデータ (カウンターなど) がある場合は、そこにミューテックスが必要であることを意味します。

スレッドが、他のスレッドが待機している可能性のある共有データの状態に変更を加えた場合は、条件変数にシグナルを送って通知します。(たとえば、Producer スレッドがキューにデータを追加する場合、Consumer が待機している「dataAvailable」条件を通知する可能性があります。)

于 2010-05-25T02:27:44.473 に答える
1

私には、あなたがランデブー (Ada からの言葉) をしようとしているように見えます。

2 番目のスレッドは座って、最初のスレッドがそれを呼び出すのを待っています。次に、最初のスレッドが待機している間、すぐにいくつかの作業を行い、最初のスレッドが終了した後にさらに作業を行います。

最初のスレッドは 2 番目のスレッドを「呼び出し」ています。2 番目のスレッドが呼び出しに対応できない場合は、すぐにタイムアウトになります。

Ada はこれを言語で直接サポートしていますが、Ada への移植はオプションではないと仮定します...

これは、3 つのセマフォで実装できます。セマフォ 1 は、スレッド 1 がランデブーする準備ができていることを示します。セマフォ 2 は、スレッド 2 がランデブーする準備ができていることを示します。セマフォ 3 は、ランデブーが完了したことを示します。

スレッド 1: デフォルトでセマフォ 1 が取得されます。

 if Semaphore 2.acquire(timeout = 0) is successful # Thread 2 is ready
     Semaphore 1.release() # Indicate I am ready
     Semaphore 3.acquire() # Wait until the rendevous is complete.
     Semaphore 3.release()
     Semaphore 1.acquire() # Indicate I am not ready
     Semaphore 2.release() # I am no longer using thread 2.

 Do concurrent work 

スレッド 2: セマフォ 2 を取得したデフォルト。

 Loop forever
     Semaphore 3.acquire() # Indicate Rendevous is not complete.
     Semaphore_2.release() # Indicate I am ready
     Semaphore_1.acquire() # Wait for Thread 1 to be ready
     Joint processing
     Semaphore 1.release() # I am no longer using thread 1.
     Semaphore 3.release() # Rendevous is complete.
     Semaphore 2.acquire() # I am not ready

 Post-processing

注:ゼロから作成されたものであり、テストされていません。始めたときに思っていたよりもはるかに複雑に見えます。私は何かを逃しましたか?

于 2010-05-25T02:35:10.353 に答える