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

linux下多线程服务器处理程序问题解决

问题描述:

                  程序本意是来一个客户端连接就创建一个线程与其通信,并判断5秒内如无数据接收则断开连接,关闭网络描述符与回收线程资源。

    但是结果则不尽人意,运行了一段时间后,通过cd /proc/PID/      查看里面的内容,线程已经消失,但其资源未释放,后通过查看代码,怀疑是主线程传递给子线程的网络描述符未进行互斥保护,导致传递给子线程的网络描述符出差错。

    原因:

            主线程在使用pthread_create创建线程时,如果pthread_create 函数的第四个参数(指针参数)传入的值会被主线程随时修改时,这时我们的线程从pthread_create 函数的第四个参数获取的值可能就不是我们想要传入的值了。


原代码与改进后的代码(增加红色部分)

/*
  功能  :  创建TCP网络套接字
参数1 :  端口号
参数2 :  IP地址
返回值:  整型(成功返回0,失败返回-1)
 */
int Create_Tcp_Socket(short port,char *ipv4address)
{

   int reuser = 1;
   int listenSock,acceptSock;
   struct sockaddr_in caddr;
   socklen_t length;
   int result;
   pthread_t *pthreadId ;
   pthreadId = malloc(sizeof(pthread_t)*10);
   
   pthread_mutex_init(&m_Locker,NULL);           // 初始化互斥锁
   pthread_mutex_init(&lock,NULL);          
   pthread_cond_init(&m_Cond,NULL);
   
   fd_set allNetSock;
   FD_ZERO(&allNetSock);
   
   if(-1 == (listenSock = socket(AF_INET,SOCK_STREAM,0)))
   {
       perror("create listeSock failed\n");
       return -1;
   }
   setsockopt(listenSock,SOL_SOCKET,SO_REUSEADDR,&reuser,sizeof(reuser));
   
   if(-1 == (mybind(listenSock,port,ipv4address)))
    {
      perror("bind failed\n");
      return -1;
    }
    printf("bind sucessed!\n");
   
   if(-1 == listen(listenSock,10))
   {
       perror("listen failed\n");
       return -1;
   }
   
  while(1)
   {   
     
      length = sizeof(struct sockaddr_in );
      pthread_mutex_lock(&m_Locker);                // 申请互斥锁
       if(-1 == (acceptSock = accept(listenSock,(struct sockaddr*)&caddr,&length)))
         {
             perror("accept failed\n");
          sleep(1);