1

n個のスレッドを作成し、バリアが壊れた後に実行を開始しています。

グローバルデータスペース:

int bkdown = 0;

main()で:

pthread_barrier_init(&bar,NULL,n);

for(i=0;i<n;i++)
{
pthread_create(&threadIdArray[i],NULL,runner,NULL);
if(i==n-2)printf("breakdown imminent!\n");
if(i==n-1)printf("breakdown already occurred!\n");
}

スレッドランナー関数の場合:

void *runner(void *param)
{
 pthread_barrier_wait(&bar);

 if(bkdown==0){bkdown=1;printf("barrier broken down!\n");}

        ...

 pthread_exit(NULL);
}

予想される注文:

breakdown imminent!
barrier broken down!
breakdown already occurred!

実際の注文:( 繰り返しテスト済み)

breakdown imminent!
breakdown already occurred!
barrier broken down!!

"broken down"メッセージの前にメッセージが表示されない理由を誰かが説明でき"already occurred"ますか?

4

4 に答える 4

3

スレッドが実行される順序は、オペレーティングシステムによって異なります。スレッドを開始したからといって、OSがすぐに実行するわけではありません。

スレッドが実行される順序を本当に制御したい場合は、そこに何らかの同期を入れる必要があります(ミューテックスまたは条件変数を使用)。

于 2010-09-24T19:43:06.227 に答える
2
for(i=0;i<n;i++)
{
pthread_create(&threadIdArray[i],NULL,runner,NULL);
if(i==n-2)printf("breakdown imminent!\n");
if(i==n-1)printf("breakdown already occurred!\n");
}

までこのループの実行を停止するものはありませんi == n-1。pthread_create()は、実行するスレッドを起動するだけです。開始または終了するのを待ちません。したがって、あなたはスケジューラーに翻弄され、ループの実行を継続するか、新しく作成されたスレッドの1つに切り替えるか(またはSMPシステムで両方を行うか)を決定する可能性があります。

また、へのバリアを初期化しているnため、いずれの場合も、すべてのスレッドを作成するまで、どのスレッドもバリアを通過しません。

于 2010-09-24T19:44:41.403 に答える
1

nosとStarkeyの答えに加えて、コードに別のシリアル化があり、それがしばしば無視されることを考慮に入れる必要があります。FILEつまり、同じ変数でIOを実行しているということstdinです。

その変数へのアクセスは内部n+1でミューテックスされ、スレッド(呼び出し元のスレッドを含む)がそのミューテックスにアクセスする順序は実装で定義されています。基本的にはランダムです。

したがって、出力を取得するprintf順序は、スレッドがこれらのワームホールを通過する順序です。

于 2010-09-24T21:36:50.033 に答える
0

2つの方法のいずれかで期待される注文を取得できます

  • メインスレッドよりも高い優先度で各スレッドを作成します。これにより、新しいスレッドが作成直後に実行され、バリアで待機するようになります。
  • 「breakdownimminent!\ n」の印刷をpthread_create()の前に移動し、すべてのpthread_create()の後にsched_yield()呼び出しを使用して呼び出します。これにより、新しく作成されたスレッドの実行がスケジュールされます。
于 2011-05-20T08:33:37.290 に答える