日期:2014-05-16 浏览次数:20757 次
先看一个有问题的例子:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <semaphore.h> void * pthread_function(void * arg); #define MAX_SIZE 10 int main(int argc, char const *argv[]) { pthread_t pthread[MAX_SIZE]; pthread_attr_t pthread_attr; int res; void * pthread_result; res = pthread_attr_init(&pthread_attr); if (res != 0) { perror("pthread_attr_init failed!"); exit(EXIT_FAILURE); } pthread_attr_setdetachstate(&pthread_attr,PTHREAD_CREATE_DETACHED); int i; for ( i = 0; i < MAX_SIZE; ++i) { res = pthread_create(&pthread[i], NULL, pthread_function, (void *)&i); // res = pthread_create(&pthread[i], NULL, pthread_function, (void *)i); if (res != 0) { perror("pthread_create failed!"); exit(EXIT_FAILURE); } } // printf("wait for the threads to finish!\n"); // for (i = MAX_SIZE-1; i >= 0; --i) // { // res = pthread_join(&pthread[i],&pthread_result); // if (res == 0) // printf("pick up a thread!\n"); // else // { // perror("pick up a thread failed!\n"); // } // } // while(i == MAX_SIZE) break; sleep(1); printf("All done!\n"); return 0; } void * pthread_function(void *arg) { int mynum = *(int*)arg; // int mynum = (int)arg; printf("the thread num is : %d\n",mynum); pthread_exit(NULL); }
我本意想创建多个线程,然后把他们的线程号随机打印出来,结果出现一样的mynum,不是想要的结果。出现这样的原因是:启动线程时,线程函数的参数是一个局部变量,这个变量在循环中被更新,所以出现这种现象。
出现问题的地方:
在创建线程的时候,最后一个参数局部变量可能被更新,因为主线程运行很快,最后一个参数是传地址,可能在传一个地址的那一刻,i加了两次。
解决办法:
把值当作地址传递,然后打印地址。
代码如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <semaphore.h> void * pthread_function(void * arg); #define MAX_SIZE 10 int main(int argc, char const *argv[]) { pthread_t pthread[MAX_SIZE]; pthread_attr_t pthread_attr; int res; void * pthread_result; res = pthread_attr_init(&pthread_attr); if (res != 0) { perror("pthread_attr_init failed!"); exit(EXIT_FAILURE); } pthread_attr_setdetachstate(&pthread_attr,PTHREAD_CREATE_DETACHED); int i; for ( i = 0; i < MAX_SIZE; ++i) { // res = pthread_create(&pthread[i], NULL, pthread_function, (void *)&i); res = pthread_create(&pthread[i], NULL, pthread_function, (void *)i); if (res != 0) { perror("pthread_create failed!"); exit(EXIT_FAILURE); } } // printf("wait for the threads to finish!\n"); // for (i = MAX_SIZE-1; i >= 0; --i) // { // res = pthread_join(&pthread[i],&pthread_result); // if (res == 0) // printf("pick up a thread!\n"); // else // { // perror("pick up a thread failed!\n"); // } // } // while(i == MAX_SIZE) break; sleep(1); printf("All done!\n"); return 0; } void * pthread_function(void *arg) { // int mynum = *(int*)arg; int mynum = (int)arg; printf("the thread num is : %d\n",mynum); pthread_exit(NULL); }