浅谈并发服务器----多线程并发----2


                      接下来看两个程序,是对于线程参数传递问题。


第一种传参方式:

/*
 * =====================================================================================
 *
 *       Filename:  thread1.c
 *
 *    	 Description:  线程参数传递
 *
 *       Version:  1.0
 *       Created:  2014年07月20日 17时17分57秒
 *       Revision:  none
 *       Compiler:  gcc
 *	 CopyRight: open , free , share
 *       Author:  yexingkong(zhangbaoqing)
 *	 Email: abqyexingkong@gmail.com
 *       Company:  Xi'an University of post and Telecommunications
 *
 * =====================================================================================
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>



#define	PORT	1234			/*端口定义*/
#define	 BACKLOG	15			/*监听队列大小*/


struct ARG{
	int connfd;
	int other;
};



/* -------------------------------------------------------------------*/
/** 
 * @Synopsis=   线程函数
 * 
 * @Param= arg  从主线程传递给线程函数的参数
 * 
 * @Returns=  
 */
/* ----------------------------------------------------------------------------*/
void *funtion(void *arg)
{
	struct ARG  info;
	info.connfd = ((struct ARG *)arg) -> connfd;
	info.other = ((struct ARG *)arg) -> other;
	printf("test");
	close(info.connfd);
	pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
	struct ARG arg;        //多个线程共享此变量
	int connfd,sockfd;
	pthread_t tid;

	.......

	while(1)
	{
		if ((connfd = accept(sockfd,NULL,NULL)) == -1)
		{
			//handle excepton
		}
		arg.connfd = connfd;
		if(pthread_create(&tid,NULL,funtion,(void *)&arg) != 0) //将共享变量arg传递给多个线程
		{
			//handle exception
		}
	}

	return EXIT_SUCCESS;
}

第二种传参方式:

/*
 * =====================================================================================
 *
 *       Filename:  thread1.c
 *
 *    	 Description:  线程参数传递
 *
 *       Version:  1.0
 *       Created:  2014年07月20日 17时17分57秒
 *       Revision:  none
 *       Compiler:  gcc
 *	     CopyRight: open , free , share
 *       Author:  yexingkong(zhangbaoqing)
 *	     Email: abqyexingkong@gmail.com
 *       Company:  Xi'an University of post and Telecommunications
 *
 * =====================================================================================
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>



#define	PORT	1234			/*端口定义*/
#define	 BACKLOG	15			/*监听队列大小*/


struct ARG{
	int connfd;
	int other;
};



/* -------------------------------------------------------------------*/
/** 
 * @Synopsis=   线程函数
 * 
 * @Param= arg  从主线程传递给线程函数的参数
 * 
 * @Returns=  
 */
/* ----------------------------------------------------------------------------*/
void *funtion(void *arg)
{
	struct ARG  info;
	info.connfd = ((struct ARG *)arg) -> connfd;
	info.other = ((struct ARG *)arg) -> other;
	printf("test");
	close(info.connfd);
	free(arg);
	pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
	struct ARG  *arg;     // 注意和上移程序的不同之处   
	int connfd,sockfd;
	pthread_t tid;

//此处自行添加服务器或客户端的tcp/upd链接
	.......

	while(1)
	{
		if ((connfd = accept(sockfd,NULL,NULL)) == -1)
		{
			//handle excepton
		}
		//注意此处和前一个程序的不同之处
		arg = (struct ARG *)malloc(sizeof(struct ARG));
		arg -> connfd = connfd;

		if(pthread_create(&tid,NULL,funtion,(void *)&arg) != 0) //将共享变量arg传递给多个线程
		{
			//handle exception
		}
	}

	return EXIT_SUCCESS;
}

                      这两种传参方式的不同之处就在于,在第一种方式中,arg变量是所有线程共用的,而且给线程函数传递参数时,传递的是共享变量的地址,所以就有可能发生,再有多个客户链接请求时,线程A在处理客户A的请求时,执行了线程函数,而同时线程B也在处理客户B请求,那么线程A将修改arg中的内容,这时,线程B再从arg中获得的信息实际上是客户A的信息。这样就会导致arg中的值出现紊乱。

                      那又有什么办法避免这种冲突呢?可以通过为arg分配空间来解决这个问题,首先为每个新线程分配存储arg的空间,再将arg传递给新线程,新线程使用后释放分配的arg空间,也就是第二种传参方式,在有一个客户端链接后就为arg创建创建独立的空间,这样每个线程就有一个属于他们自己的arg空间,这样就不会共享arg空间,也就不会造成错乱。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值