日期:2014-05-16 浏览次数:20904 次
先看一个有问题的例子:
#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);
}
