質問

私は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" メッセージ?

役に立ちましたか?

解決

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, 、したがって、いずれにせよ、すべてのスレッドを作成するまで、スレッドは障壁を乗り越えません。

他のヒント

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

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

NOSとStarKeyの回答に加えて、あなたはあなたのコードに別のシリアル化があることを考慮する必要があります。 FILE 変数、つまり stdin.

その変数へのアクセスは内部的に変異し、あなたの順序は n+1 スレッド(呼び出しスレッドを含む)は、そのMutexが定義されている実装であることにアクセスし、基本的にランダムにしてください。

だからあなたがあなたを手に入れる順序 printf 出力とは、スレッドがこれらのワームホールを通過する順序です。

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

  • メインスレッドよりも優先度が高い各スレッドを作成します。これにより、作成直後に新しいスレッドが実行され、障壁が待機することが保証されます。
  • PTHREAD_CREATE()の前に「BreakDown -Imnint! n」を移動し、PTHREAD_CREATE()ごとにsched_yield()呼び出しを使用します。これにより、新しく作成されたスレッドが実行されます。
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top