1

私はmutexを使用してpthreadをテストしようとしていました:

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int global = 0;
void thread_set();
void thread_read();



int main(void){
  pthread_t thread1, thread2;
  int re_value1, re_value2;
  int i;
  for(i = 0; i < 5; i++){
    re_value1 = pthread_create(&thread1,NULL, (void*)&thread_set,NULL);
    re_value2 = pthread_create(&thread2,NULL,(void*)&thread_read,NULL);
  }

  pthread_join(thread1,NULL);
  pthread_join(thread2,NULL);
  /* sleep(2); */ // without it the 5 iteration couldn't finish
  printf("exsiting\n");
  exit(0);
}

void thread_set(){
  pthread_mutex_lock(&mutex1);
  printf("Setting data\t");
  global = rand();
  pthread_mutex_unlock(&mutex1);
}
void thread_read(){
  int data;
  pthread_mutex_lock(&mutex1);
  data = global;
  printf("the value is: %d\n",data);
  pthread_mutex_unlock(&mutex1);
}

がないsleep()と、コードは5回の反復を終了しません。

設定データ値は次のとおりです:1804289383値は次のとおりです:1804289383設定データ値は次のとおりです:846930886既存

設定データ値は次のとおりです:1804289383設定データ値は次のとおりです:846930886値は次のとおりです:846930886既存

これは、sleep()をメインスレッドに追加するだけでsleep()機能します。join()関数は各子スレッドが終了するのを待つため、なしでも機能するはずです。

なぜだと誰でも教えてくれますか?

4

2 に答える 2

1

ミューテックスオブジェクトの使用は問題ないように見えますが、このループ

for(i = 0; i < 5; i++) {
     re_value1 = pthread_create(&thread1,NULL, (void*)&thread_set,NULL);
     re_value2 = pthread_create(&thread2,NULL,(void*)&thread_read,NULL);
}

同じスレッドインスタンスthread1を再利用しているthread2ため、ループの反復ごとに問題が発生しています。内部的にはこれが問題を引き起こしているに違いありませんが、それがどのように現れるかは正確にはわかりません。信頼性の高い実行を保証するには、スレッドごとにスレッドオブジェクトの個別のインスタンスを実際に使用する必要があります。すでに実行されているスレッドオブジェクトのインスタンスを使用して呼び出した場合にどうなるかはわかりませんがpthread_create、それは賢明なことではないと思います。せいぜい、スレッド関数が終了するまでブロックされるのではないかと思います。

pthread_create()また、どちらからの戻り値もチェックしていないので、これは良い考えかもしれません。要約すると、スレッドオブジェクトの別のインスタンスを使用するかpthread_join、ループの内側に呼び出しを追加して、次のへの呼び出しの前にスレッドの実行が終了することを確認しますpthread_create()

最後に、渡される関数の関数シグネチャpthread_create()は次のタイプです。

 void* thread_function(void*);

ではなく

 void thead_function()

あなたがあなたのコードに持っているように。

于 2012-08-08T15:54:20.487 に答える
1

10個のスレッド(それぞれ2つのスレッドの5回の反復)を作成していますが、作成した最後の2つだけを結合しています(mathematician1975が指摘しているように、スレッドハンドル変数を再利用しているため、最後の反復の値だけが参加可能です)。がないとsleep()、を押す前にスケジューラが最初の8スレッドの実行を開始していない可能性がありますexit()。これにより、スレッドがまだ実行されているかどうかに関係なく、すべてのスレッドが自動的に終了します。

于 2012-08-08T16:06:49.147 に答える