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

来源:互联网 发布:3d打印笔 淘宝 编辑:程序博客网 时间:2024/06/16 10:10


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


第一种传参方式:

/* * ===================================================================================== * *       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>#definePORT1234/*端口定义*/#define BACKLOG15/*监听队列大小*/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>#definePORT1234/*端口定义*/#define BACKLOG15/*监听队列大小*/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空间,也就不会造成错乱。




0 0