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);
          continue;      
         }
       else 
        {
         if( 0 != (result =  pthread_create((pthreadId + (acceptSock - 4)),NULL,(void*)different_client_pthread_handle_fun,&acceptSock)))
          {
            perror("child pthread failed\n");
            exit(1);
          }
          
          pthread_t tid;
           tid = pthread_self();
           printf("main thread is %u\n",(unsigned int )tid );
           pthread_detach(*(pthreadId + (acceptSock - 4)));
        }
        pthread_cond_wait(&m_Cond,&m_Locker);       // 用于阻塞线程,等待其它线程释放m_Locker锁。
        pthread_mutex_unlock(&m_Locker);            // 释放互斥锁    

        /*
        FD_SET(acceptSock,&allNetSock);
         if(1)
        driving_send_alarm_info(&allNetSock);
        */
   }
close(listenSock);
free(pthreadId);
}


/*
  功能  :  处理不同客户端线程服务函数
参数1 :  网络描述符
        返回值:  无
 */
void* different_client_pthread_handle_fun(void *arg)
{

  pthread_mutex_lock(&m_Locker);                      // 申请互斥锁
   int fd = *(int*)arg;
   printf("fd is %d\n",fd);
   pthread_cond_signal(&m_Cond);                       // 发送信号给主线程,使其对m_Locker的拥有
   pthread_mutex_unlock(&m_Locker);                    // 释放互斥锁   

   
   pthread_t tid;
   tid = pthread_self();
   printf("child thread is %u\n",(unsigned int )tid );


   
   int result;
   fd_set readfds;
   struct timeval tv;
   
   FD_ZERO(&readfds);
   FD_SET(fd,&readfds);
   while(1)
   {
   }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值