0

マルチスレッドを学んでいます。に関して

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SCHEDULING

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>


pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;



void *functionCount1();
void *functionCount2();

int  count = 0;

#define COUNT_DONE  10
#define COUNT_HALT1  3
#define COUNT_HALT2  6



main()
{
   pthread_t thread1, thread2;
   pthread_create( &thread1, NULL, &functionCount1, NULL);
   pthread_create( &thread2, NULL, &functionCount2, NULL);



   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   printf("Final count: %d\n",count);

   exit(0);
}



// Write numbers 1-3 and 8-10 as permitted by functionCount2()

void *functionCount1()
{
   for(;;)
   {
      // Lock mutex and then wait for signal to relase mutex
      pthread_mutex_lock( &count_mutex );



      // Wait while functionCount2() operates on count
      // mutex unlocked if condition varialbe in functionCount2() signaled.

      pthread_cond_wait( &condition_var, &count_mutex );

      count++;

      printf("Counter value functionCount1: %d\n",count);
      pthread_mutex_unlock( &count_mutex );

      if(count >= COUNT_DONE) return(NULL);
    }
}



// Write numbers 4-7



void *functionCount2()
{
   for(;;)
    {
       pthread_mutex_lock( &count_mutex );

       if( count < COUNT_HALT1 || count > COUNT_HALT2 )
       {
          // Condition of if statement has been met.
          // Signal to free waiting thread by freeing the mutex.
          // Note: functionCount1() is now permitted to modify "count".

          pthread_cond_signal( &condition_var );
       }
       else
       {
          count++;
          printf("Counter value functionCount2: %d\n",count);
       }



       pthread_mutex_unlock( &count_mutex );

       if(count >= COUNT_DONE) return(NULL);
    }
}

コードの制御の流れを知りたいです。

としてpthread_cond_wait - unlocks the mutex and waits for the condition variable cond to be signaled

フローの制御について私が理解したのは、

1) スレッド 1、2 が作成され、スレッド 1 に制御が渡されます (シングル コア プロセッサ システムを考慮)

2)ルーチンで発生pthread_cond_wait( &condition_var, &count_mutex );した場合- ロックを解放し、制御を渡して待機状態に移行します。thread1void *functionCount1()thread2 void *functionCount1()

3)thread2変数countでチェックされ、それが満たされているcount < COUNT_HALT1 || count > COUNT_HALT2ため、信号thread1を送って再起動することはインクリメントすることですcount

4)Steps 2 to 3が繰り返されます1-3thread1

5) thread2 が動作中であり、とcount 4-7の間の切り替えがない場合thread1thread2

6)count 8-10再びsteps 2-3繰り返されます。

私の理解が正しいかどうか知りたいですか?はスリープthread1状態になり、スリープ状態からthread2復帰します (つまり、スレッドが切り替えられcount value 1-3 and 8-10 i.e switching between threads happen 5 timesます)。

編集

この質問をする私の主な関心事は、それが遭遇したときthread1に状態に行き、それからのみインクリメントによって通知されない限り再び状態にならないかどうかを知ることです。からの信号の場合のみ、さらに進むことができますsleeppthread_cond_wait( &condition_var, &count_mutex );activethread2count1-3thread2

4

3 に答える 3

3

まず、ブテンホフの本を手に入れて、勉強してください。あなたが引用したページはいくつかの場所で間違っており、著者は明らかにスレッド自体を理解していません.

あなたの質問に関して: 最初に言うことは、コードの制御フローについて知ることができないということです。これはスレッディングの特徴であり、最近のプロセッサでは、スレッドが実際に並行して実行されていることがよくあります。つまり、1 つのコアが 1 つのスレッドを実行し、別のコアが別のスレッドを実行します。また、各スレッド内で、プロセッサが予期しない方法でメモリ アクセスを再配置する場合があります。たとえば、これがミューテックスが必要な理由です。(「シングルコア処理系を検討中」とおっしゃっていますが、実際にはシングルコアの汎用系はもう存在しません。)

次に、スレッドのスケジュール方法はオペレーティング システムに依存します。たとえば、コードでは、開始functionCount2前に完了するまで実行できます。これは、永遠に待機functionCount1することを意味します。functionCount1

第 3 に、スレッドがpthread_cond_wait誤ってウェイクアップする可能性があります。ループ内にあることは絶対的なルールでpthread_cond_waitあり、実際に待っている条件が何であれチェックします。たぶん次のようなもの:

while ( count > COUNT_HALT1 && count < COUNT_HALT2 ) {
    pthread_cond_wait( &condition_var, &count_mutex );
}

最後に、countミューテックスで保護されていないセクションにアクセスしている場合があります。これは未定義の動作です。へのすべての アクセスをcount保護する必要があります。あなたの場合、ロックとロック解除はおそらくプログラムループの外にあるはずであり、両方のスレッドは条件変数を待つ必要があります。(しかし、これは明らかに人為的な状況です。実際には、ほとんどの場合、プロデューサー スレッドとコンシューマー スレッドが存在します。)

于 2013-05-15T08:56:49.103 に答える
2

理想的な世界ではそうですが、実際にはそうではありません。

どの踏み板が最初に制御されるかは予測できません。はい、そうなる可能性がありますがthread1、まだ保証されていません。これは、コード内の最初の競合状態です。

制御を取得すると、ほとんどの場合thread2、停止せずに終了します。CPU の数に関係なく。その理由は、yield 無条件に置く場所がないからです。を解放mutexしたからといって、誰でもロックできるわけではありません。コード内の 2 番目の競合状態です。

したがって、 はthread1を出力11し、それが保証される唯一の部分です。

于 2013-05-15T08:06:05.380 に答える
1

1) スレッドが作成されます。制御はスレッド 1 に渡されません。実行するスレッドを決定するのはシステム スケジューラです。両方のスレッドがアクティブであり、どちらもプロセッサ時間を受け取る必要がありますが、順序は決定されていません。いくつかのコンテキスト スイッチが存在する可能性がありますが、これを実際に制御することはできません。

2) 正しく、スレッド 1 は待機状態になり、スレッド 2 は引き続き動作します。繰り返しますが、制御は明示的に渡されません。

3) はい、スレッド 2 は条件変数を通知するため、スレッド 1 は起動してミューテックスを再取得しようとします。制御はすぐにスレッド 1 に移動しません。

一般に、実行するスレッドを実際に制御することはできないことを理解する必要があります。それはシステム スケジューラの仕事であり、必要な数のコンテキスト スイッチを配置できます。

UPD: 条件変数を使用すると、マルチスレッド環境内でタスクの実行順序を制御できます。したがって、あなたの理解は多かれ少なかれ正しいと思います.thread1は、thread2からのシグナルを条件変数で待機しています。シグナルが受信されると、thread1 は実行を継続します (mutex を再取得した後)。しかし、スレッド間の切り替え - スレッドの数が多い可能性があります。5 は理論上の最小値にすぎません。

于 2013-05-15T08:07:08.853 に答える