multithreadingC程序中的线程ID错误?

我是C语言中的multithreading新手,我有这个问题。 我写了以下代码:

#include  #include  #include  pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER; pthread_attr_t attr; void* test(void *a) { int i=*((int *)a); printf("The thread %d has started.\n",i); pthread_mutex_lock(&m); sleep(1); printf("The thread %d has finished.\n",i); pthread_mutex_unlock(&m); pthread_exit(NULL); } int main() { int i=0; pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); pthread_t thread[5]; for (i=0;i<5;i++) pthread_create(&thread[i],&attr,test,&i); for (i=0;i<5;i++) pthread_join(thread[i],NULL); return 0; } 

为什么我会得到如下值:

 The thread 0 has started. The thread 0 has started. The thread 5 has started. The thread 5 has started. The thread 0 has started. The thread 0 has finished. The thread 0 has finished. The thread 5 has finished. The thread 5 has finished. The thread 0 has finished. 

要么

 The thread 1 has started. The thread 2 has started. The thread 5 has started. The thread 4 has started. The thread 0 has started. The thread 1 has finished. The thread 2 has finished. The thread 5 has finished. The thread 4 has finished. The thread 0 has finished. 

甚至:

 The thread 0 has started. The thread 0 has started. The thread 0 has started. The thread 0 has started. The thread 0 has started. The thread 0 has finished. The thread 0 has finished. The thread 0 has finished. The thread 0 has finished. The thread 0 has finished. 

等,当我期望得到:

 The thread 0 has started. The thread 1 has started. The thread 2 has started. The thread 3 has started. The thread 4 has started. The thread 0 has finished. The thread 1 has finished. The thread 2 has finished. The thread 3 has finished. The thread 4 has finished. 

只有当我在thread_create之后放入usleep(10)才会得到一些“正常”值。

我在Unix上的Code :: Blocks中编译并运行了这段代码。

请注意,您将i的地址作为参数传递给线程:

 pthread_create(&thread[i],&attr,test,&i); 

这意味着所有线程都将读取相同的变量i以确定它们是哪个线程。 也就是说,所有五个线程都将查看相同的变量以确定其线程号。 因此,当i的值在for循环中递增时,所有线程都会感知其线程号更改为使用i的新值。 这就是为什么你有时会看到5出现作为主题号码,并且还解释了你经常跳过数字或看到太多重复的事实。

要解决这个问题,您需要为每个线程提供自己的i副本。 例如,你可以这样做:

 int* myI = malloc(sizeof(int)); *myI = i; pthread_create(&thread[i], &attr, test, myI); 

然后让线程在终止之前释放指针:

 void* test(void *a) { int i=*((int *)a); printf("The thread %d has started.\n",i); pthread_mutex_lock(&m); sleep(1); printf("The thread %d has finished.\n",i); pthread_mutex_unlock(&m); pthread_exit(NULL); free(a); } 

或者,您可以将i转换为void*并将其传递给:

 pthread_create(&thread[i],&attr,test, (void*)i); 

如果你这样做,你就会让线程直接将其参数转换回int ,而不是int*

 void* test(void *a) { int i = (int)a; printf("The thread %d has started.\n",i); pthread_mutex_lock(&m); sleep(1); printf("The thread %d has finished.\n",i); pthread_mutex_unlock(&m); pthread_exit(NULL); } 

希望这可以帮助!

你正在传递一个变量的地址, for正在改变( i )所以你受调度程序的支配。 你应该传递一份副本。 作为一种廉价而非完全犹太的方式:

 pthread_create(&thread[i],&attr,test, (void*)i); /* ... */ int i = (int)a;