先看一个有问题的例子:
#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);
}