为什么子线程阻塞在我的代码中?

时间:2012-08-08 15:46:35

标签: pthreads 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 exsiting

设置数据的值为:1804289383 设置数据的值为:846930886 值为:846930886 exsiting

它只能将sleep()添加到主线程,我认为它应该在没有sleep()的情况下工作,因为join()函数等待每个子线程终止

任何人都可以告诉我它为什么会这样?

2 个答案:

答案 0 :(得分: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);
}

在您循环的每次迭代中重复使用相同的线程实例thread1thread2时会遇到麻烦。在内部,这必然会引起问题,虽然我不知道它将如何表现出来。您应该确实为每个线程使用一个单独的线程对象实例,以确保可靠运行。我不知道如果你使用已经运行的线程对象的实例调用pthread_create会发生什么,但我怀疑这不是明智之举。我怀疑它最多会阻塞,直到线程函数退出。

此外,您也不会从pthread_create()获取返回值,这可能是一个好主意。总之,我将使用一个单独的线程对象实例,或者将pthread_join调用添加到循环内部,以便在下一次调用pthread_create()之前确定线程已完成运行。< / p>

最后,传递给pthread_create()的函数的函数签名属于

类型
 void* thread_function(void*);

而不是

 void thead_function()
就像你的代码一样。

答案 1 :(得分:1)

您正在创建10个线程(每个线程有5个迭代),但只加入您创建的最后两个线程(作为数学家1975注释,您将重新使用线程句柄变量,因此上次迭代的值是只有你可以加入的人)。如果没有sleep(),调度程序很可能在您点击exit()之前没有开始执行前8个线程,这会自动终止所有线程,无论它们是否有机会运行。< / p>