2

グローバル変数、ミューテックス、条件変数を共有する 3 つの POSIX スレッドを持つ C プログラムがあり、そのうちの 2 つが次の疑似コードを実行しているとします。

...process data...
pthread_mutex_lock( &mutex );
variable = data_ptr;
pthread_cond_signal( &cond );
pthread_mutex_unlock( &mutex );

そして3回目の実行:

while(1) {
    while( variable == NULL ) {
        pthread_mutex_wait( &cond, &mutex );
    }
    printf( "Data is %d", *variable );
}

3 番目のスレッドが最初の 2 つのスレッドのそれぞれからのデータを見ると仮定しても安全でしょうか?

別の言い方をすれば、スレッドがミューテックスと条件変数を待機している場合、ロックを待機している可能性のある他のスレッドではなく、シグナルが送信された場合にロックを取得する次のスレッドであると想定しても安全ですか?ロック?

4

3 に答える 3

12

pthread_mutex_wait のようなものはありません。私はあなたが意味すると思います:

pthread_mutex_lock(&mutex);
/* ... */
while (1) {
  while (variable == NULL)
    pthread_cond_wait(&cond, &mutex);
  printf("Data is %d", *variable);
}
/* ... */
pthread_mutex_unlock(&mutex);

3 番目のスレッドが両方のデータを参照できるという保証はありません。pthread_cond_signal は 3 番目のスレッドを呼び起こしますが、mutex をすぐには取得しない場合があります。他のライターの 1 人が最初にミューテックスを取得する場合があります。ただし、もう少し作業を行うことで、必要なものを達成できます。

void put(int *p) {
  pthread_mutex_lock(&mutex);
  while (variable)
    pthread_cond_wait(&cond_empty, &mutex);
  variable = p;
  pthread_cond_signal(&cond_full);
  pthread_mutex_unlock(&mutex);
}

int *get() {
  int *ret;

  pthread_mutex_lock(&mutex);
  while (!variable)
    pthread_cond_wait(&cond_full, &mutex);
  ret = variable;
  variable = NULL;
  pthread_cond_signal(&cond_empty);
  pthread_mutex_unlock(&mutex);

  return ret;
}

変数が読み取られるのを明示的に待機することで、潜在的な競合状態を回避します。

于 2009-08-03T15:11:23.547 に答える
1

これが私が標準で見つけたものです:

4.13 スケジューリング方針

スケジューリング ポリシーは、プロセスまたはスレッドの順序付けに影響します。

[...]

  • プロセスまたはスレッドがブロックされたスレッドであり、実行可能なスレッドになる場合

適合する実装は、各スケジューリング ポリシーが優先度を変更する方法、または上記の発生のそれぞれでプロセスまたはスレッドの順序付けに影響を与える方法を定義するものとします。さらに、適合する実装は、他のどのような状況で、どのような方法で各スケジューリング ポリシーが優先度を変更したり、プロセスやスレッドの順序に影響を与えたりするかを定義するものとします。

したがって、明らかに未定義です。当然のことですが、一般的に言えば、どの実行可能なスレッドが実行されるようにスケジュールされているかについて、何も推測することはできません。

于 2009-08-03T15:12:57.477 に答える
0

pthread_cond_waitマンページによると

ブロックが解除されたスレッドは、(該当する場合) スケジューリング ポリシーに従って、それぞれが () を呼び出したかのようにミューテックスを求めて競合しますpthread_mutex_lock

残念ながら、私が知る限り、希望する動作を提供する利用可能なスケジューリング ポリシーはありません。

于 2009-08-03T15:13:03.077 に答える