0

私は、Operative System コースのセマフォと同期に関する演習 (以下の太字を参照) に取り組んでいます。演習のテキストは次のとおりです。

Pthread セマフォとミューテックス

C プログラム gen_binary_numbers.c は、コマンド ラインで整数 n を受け取り、再帰を使用して n ビットのすべての 2 進数を生成して表示します。再帰的なプログラムを並行プログラムに変換し、再帰的な手順を、2 進数を (任意の順序で) 表示する適切な数のプロセスの生成に置き換えます。

これは実際には私のコードです:

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

int num, r, c;
pthread_mutex_t mutex;
void *genBin(void *arg);

int main (int argc, char **argv) {
  if (argc != 2) {
    fprintf(stdout, "\nUSAGE: %s <n>\n\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  int i;
  num = atoi(argv[1]);
  c = num;
  r = 2;
  for (i=1; i<num; i++) {
    r=r*2;
  }

  pthread_mutex_init(&mutex, NULL);
  pthread_t* p;
  p = malloc(r*sizeof(pthread_t));

  for (i=0;i<r;i++) {
    if (pthread_create(&p[i], NULL, genBin, &i)) {
      fprintf(stderr, "Error creating thread.\n");
      exit(EXIT_FAILURE);
    }
  }
  pthread_exit(0);
}

void *genBin (void *arg) {
  int x;
  int i=0;
  x = *((int*)arg);

  pthread_mutex_lock(&mutex);

  while (i<num) {
    if(x!=0) {
      fprintf(stdout, "%d", x%2);
    }
    else {
      fprintf(stdout, "0");
    }
    i++;
    x/=2;
  }
  fprintf(stdout, "\n");
  pthread_mutex_unlock(&mutex);
  pthread_exit(0);
}

コードは正しい解を返すはずだと思いますが、出力が正しい数値を返さないことがあります。

正しい出力の例:

./genBin 3
100
101
010
110
001
011
111
000

誤った出力の例 (重複による):

./genBin 3
110
110
110
001
011
111
111
000

問題は、ミューテックスとprintfの間の同期にあると思います。混乱を招く結果を避けるための代替ソリューションはありますか?

4

3 に答える 3

1

問題はこの部分にあります:

  for (i=0;i<r;i++) {
    if (pthread_create(&p[i], NULL, genBin, &i)) {
      fprintf(stderr, "Error creating thread.\n");
      exit(EXIT_FAILURE);
    }
  }

すべてのスレッドにアドレスを渡すため、データ競合が発生します。i一時配列を使用して、個々の番号を各スレッドに渡すことができます。

于 2016-12-30T16:30:17.967 に答える