日期:2014-05-16  浏览次数:20757 次

linux 多线程小例子

先看一个有问题的例子:

#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);
}