在多线程中,recv非阻塞模式带来的问题

       一般在LINUX服务器应用,在多线程编程中用recv非阻塞模式同时接受属于各自描述符的网络数据。因为大量的数据同时进来,recv可能会出现阻塞状态,并且极有可能完全阻塞从而导致线程阻塞。(不过有一种情况,就是client端给再次给服务器发送数据时,可能会触发阻塞中的recv接受返回,但是概率极小)。
        这会使相应的线程永久阻塞得不到释放,运行一段时间最终将耗尽系统内存以及描述符资源,最终导致系统瘫痪。
        根本的错误原因还没发找到,暂时只能先绕开问题,选择其他方法。经多天测试发现,将recv非阻塞模式换成阻塞模式可解决问题,用select模型代替recv非阻塞模式问题也得到解决。

 

原长生错误代码如下

for(i=0; i < 3; i ++)

{

       if(recv(sockfd,&loginmsg, sizeof(loginmsg), MSG_DONTWAIT) > 0) //设置非阻塞recv模式

     {//处理登陆事件

      }

      sleep(1);

}

 

这段代码是在线程中执行的,一个来一个连接开一个线程处理,recv虽设为非阻塞模式,但是在连接很多的情况下,却有可能阻塞。不得其解。

 

 

修改代码后:

        LoginInfo buff;
        memset(&buff, 0, sizeof(buff));

        fd_set fdrr;
        struct timeval tv;

        tv.tv_sec = 3;
        tv.tv_usec = 0;
        FD_ZERO(&fdrr);
        FD_SET(fd_A[id], &fdrr);

        if (select(fd_A[id] + 1, &fdrr, NULL, NULL, &tv) <= 0)
        {
                flag = -1;
        }

        if (FD_ISSET(fd_A[id],&fdrr))
        {
                if (recv(fd_A[id], &buff, sizeof(buff), 0) > 0)
                {
                       //处理登陆事件                }
        }

不会再出现问题了。

 

本人在redhat 5.0上运行代码。问题最根本原因仍未知,有大侠知道者望能赐教。

你可能感兴趣的:(在多线程中,recv非阻塞模式带来的问题)