简单的多线程编程示例

转自http://blog.csdn.net/handyhuang/article/category/1305693

/******************************************************************************
* 文件名称: hello.c
* 文件描述: 一个类似“hello wrold”的pthread入门程序,用于说明线程(thread)的
*     创建和终止
* 文件作者: 黄玉喜 hyuxi2005@126.com
* 写作日期:2012.12.15
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define HELLO_WORLD_THREAD_NUM  5

void *hello_world_thread(void *arg)
{
   printf("pthread's Hello World!\n");
	/**  
	* @function void pthread_exit(void *status)
	*     终止调用者线程,
	* @param status:
	*     通过status设置退出状态,与pthread_join配对使用
	* @return :
	*     无返回值,也不返回到其调用方。
	* @note 
	*     如果调用线程尚未分离,则线程ID 和status 指定的退出状态将保持不变,直到应用程序调用pthread_join() 以等待该线程。
	*     否则,将忽略status。线程ID 可以立即回收。
	*/
   pthread_exit(NULL);

   return NULL;
}

int main(int argc, char *argv[])
{
	pthread_t threads[HELLO_WORLD_THREAD_NUM];
	int rc;
	int i;
	for(i=0;i<HELLO_WORLD_THREAD_NUM;i++)
	{
		/**  
		* @function int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg)
		*     按照给定的线程属性attr,在一个进程(process)里创建一个新的线程(thread)
		* @param attr:
		*     如果attr为NULL,则内部使用默认的属性创建线程。如果在创建线程之后修改attr,则不会对已经创建的线程产生作用。
		* @param thread:
		*     创建线程成功后,将thread id存储在thread里,返回给调用者。否则thrad的值是未定义的。
		* @param start_routine:
		*     线程创建成功后,开始执行线程的入口函数start_routine。
		* @param arg:
		*     调用者通过arg指定线程入口函数start_routine专用的参数指针。
		* @return :
		*     0 创建成功返回0
		*     EAGAIN 超出了系统限制,如创建的线程太多,一个进程最多创建线程个数PTHREAD_THREADS_MAX。
		*     EINVAL attr 的值无效
		* @note pthread_create创建线程后,线程入口函数即开始执行,不需要显示控制start_routine开始执行。
		*     如果确实需要将此过程分为create和start2步来控制start_routine稍后执行,
		*     start_routine可以通过等待一个条件变量(condition variable)进行同步的方式实现。
		*/
		rc = pthread_create(&threads[i], NULL, hello_world_thread, NULL);
		if (rc)
		{
			printf("ERROR: pthread_create failed with %d\n", rc);
			return -1;
		}
	}

	for(i=0;i<HELLO_WORLD_THREAD_NUM;i++)
	{
		/**  
		* @function int pthread_join(pthread_t thread, void **status);
		*     等待thread线程终止
		*     如果thread指代的线程还没有终止,将导致调用线程挂起,直到thread指代的线程终止为止。
		* @param thread:
		*     所等待的的终止线程
		* @param status:
		*     如果status的值不等于NULL,那么它的值是通过pthread_exit传递过来的。
		* @return :
		*     0 线程已经终止
		*     ESRCH 多个线程不能等待同一个线程完成,否则仅有一个线程会成功完成。其他线程将终止,并返回ESRCH 错误。
		*     EINVAL 一般表示thread是无效的参数
		*     EDEADLK 检查到死锁状态
		* @note 
		*     如果调用线程尚未分离,则线程ID 和status 指定的退出状态将保持不变,直到应用程序调用pthread_join() 以等待该线程。
		*     否则,将忽略status。线程ID 可以立即回收。
		*/
		pthread_join(threads[i], NULL);
	}
	
	printf("INFO: All threads have been exit!!!\n");

	return 0;
}



/******************************************************************************
* 文件名称: hello_arg.c
* 文件描述: 一个类似“hello wrold”的pthread入门程序,用于说明线程(thread)的
*     创建和终止,增加了hello_world_thread arg参数的示例,可以区别是哪个线程打印
*     pthread's Hello World!
* 文件作者: 黄玉喜 hyuxi2005@126.com
* 写作日期:2012.12.15
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define HELLO_WORLD_THREAD_NUM  5

void *hello_world_thread(void *arg)
{
	/* 创建线程时,arg参数传递的是int*类型,所以这里给他转换过来 */
	int id = *((int*)arg);
	
	/* 通过打印信息就知道是第几个创建的线程在执行了 */
	printf("pthread's Hello World! I am %d\n",id);

	pthread_exit(NULL);

	return NULL;
}

int main(int argc, char *argv[])
{
	pthread_t threads[HELLO_WORLD_THREAD_NUM];
	int rc;
	int i;
	int *thread_args = malloc(HELLO_WORLD_THREAD_NUM*sizeof(int));
	if(thread_args == NULL)
	{
		printf("ERROR: no memory \n");
		return -1;
	}

	for(i=0;i<HELLO_WORLD_THREAD_NUM;i++)
	{
		/* 将i值存放到 thread_args[i]*/
		thread_args[i] = i;
		/* 创建线程时,将thread_args[i]地址 作为arg参数传递给 hello_world_thread */
		/* 网上有些代码示例是用的局部变量地址作为arg参数,这是不安全的,因此我从堆上分配内存作为arg参数。 */
		rc = pthread_create(&threads[i], NULL, hello_world_thread, (void*)&thread_args[i]);
		if (rc)
		{
			printf("ERROR: pthread_create failed with %d\n", rc);
			return -1;
		}
	}

	for(i=0;i<HELLO_WORLD_THREAD_NUM;i++)
	{
		pthread_join(threads[i], NULL);
	}
	
	printf("INFO: All threads have been exit!!!\n");

	/* 别忘了释放前面分配的内存 */
	if(thread_args)
	{
		free(thread_args);
	}

	return 0;
}



/******************************************************************************
* 文件名称: hello_exit.c
* 文件描述: 一个类似“hello wrold”的pthread入门程序,用于说明线程(thread)的
*     创建和终止,在hello_arg的基础,增加对exit,join的status测试代码。
* 文件作者: 黄玉喜 hyuxi2005@126.com
* 写作日期:2012.12.15
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HELLO_WORLD_THREAD_NUM  2

void *hello_world_thread(void *arg)
{
	/* 创建线程时,arg参数传递的是int*类型,所以这里给他转换过来 */
	int id = *((int*)arg);
	
	/* 通过打印信息就知道是第几个创建的线程在执行了 */
	printf("pthread's Hello World! I am %d\n",id);
	if(id%2 ==0)
	{
		/* 如果id被2整除,将arg指代的内存释放,并分配新的内存存放status返回给pthread_join */
		char *status = malloc(strlen("i have free arg's memory")+1);
		if(status)
		{
			memset(status,0x00,strlen("i have free arg's memory")+1);
			memcpy(status,"i have free arg's memory",strlen("i have free arg's memory"));
			printf("thread %d: %s %p, but malloc %p\n",id,status, arg,status);
			free(arg);

			pthread_exit((void*)status);
		}
	}

	/* 如果id不能被2整除,或者分配新的内存status失败,将arg作为status返回给pthread_join */
	printf("thread %d: wait pthread_join free arg's memory %p\n",id,arg);
	pthread_exit(arg);

	

	return NULL;
}

int main(int argc, char *argv[])
{
	pthread_t threads[HELLO_WORLD_THREAD_NUM];
	int rc;
	int i;
	char *status=NULL;

	for(i=0;i<HELLO_WORLD_THREAD_NUM;i++)
	{
		/* 将i值存放到 thread_args[i]*/
		int *thread_arg = malloc(sizeof(int));
		if(thread_arg==NULL)
		{
			printf("ERROR: no memory!\n");
			return -1;
		}

		*thread_arg = i;

		/* 创建线程时,为每个线程单独分配内存作为arg参数 */
		printf("main: arg' memory %p\n", thread_arg);
		rc = pthread_create(&threads[i], NULL, hello_world_thread, (void*)thread_arg);
		if (rc)
		{
			printf("ERROR: pthread_create failed with %d\n", rc);
			return -1;
		}
	}

	for(i=0;i<HELLO_WORLD_THREAD_NUM;i++)
	{
		pthread_join(threads[i], &status);
		if(status)
		{
			if(memcmp(status,"i have free arg's memory",strlen("i have free arg's memory"))==0)
			{
				printf("--join %d: I'm freeing status's memory %p\n",i, status);
			}
			else
			{
				printf("--join %d: I'm freeing arg's memory  %p\n",i,status);
			}
			free(status);
		}
	}
	
	printf("INFO: All threads have been exit!!!\n");

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值