コンカレントサーバの概要---マルチスレッドコンカレント------2


次に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: [email protected]
 *       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;
}


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: [email protected]
 *       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;
}


この2つのパラメータ伝達方式の違いは、1つ目の方式ではarg変数がすべてのスレッドで共通であり、またスレッド関数にパラメータを伝達する際に共有変数のアドレスが伝達されるため発生する可能性があり、さらに複数のクライアントリンク要求がある場合、スレッドAはクライアントAの要求を処理する際にスレッド関数を実行し、同時にスレッドBもクライアントBの要求を処理し、スレッドAはargの内容を修正するが,この場合,スレッドBがargから取得した情報は実際にはクライアントAの情報である.これによりargの値が乱れます.
では、このような衝突を避ける方法はありませんか?この問題はargに空間を割り当てることによって解決することができ、まず新しいスレッドごとにargを格納する空間を割り当て、argを新しいスレッドに渡すことができ、新しいスレッドが使用された後に割り当てられたarg空間を解放すること、すなわち第2のパラメータ伝達方式は、クライアントリンクがある後にargに独立した空間を作成することで、各スレッドには独自のarg空間があり、arg空間を共有しないようにする.錯乱を起こさない.