从其他线程调用FD_SET,选择仍然阻塞

时间:2012-09-04 16:41:22

标签: c linux sockets select

我在使用单选呼叫编写第一个异步服务器时遇到了这个问题:

if( (retv = select((hsock<highestsocket?highestsocket:hsock)+1, &rFdx, &wFdx, &eFdx, 0) ) > 0)
{
   printf("select() ended...\n");
    if(FD_ISSET(hsock, &rFdx))
    {
      // .... handle new connection
    }

    for(unsigned int i=0; i < ClientList.size(); i++)
    {
      ServerClient* client = ClientList[i];

      if(FD_ISSET(client->socket, &rFdx))
      {
        // handle client read
      }
      if(FD_ISSET(client->socket, &wFdx))
      {
           // handle client write
      }    

    }
}

我希望选择停止等待,然后在从其他线程调用FD_SET时处理客户端写入。

如果我从同一个线程调用客户端套接字上的FD_SET,一切都按预期工作。 但是,从其他线程调用它什么都不做,select会一直等待,直到从客户端收到任何数据。

1 个答案:

答案 0 :(得分:2)

当然,您无法在一个线程中修改数据,并且期望在没有正确同步的情况下,修改在其他线程中可见。 select可能会在被调用时立即读取fd_set,然后再也不会再查看它;但无论如何,如果已经调用select,则无法获得必要的同步。你真的需要重新考虑你的设计。一种解决方案是“自管”技巧:打开管道select始终在寻找输入,让其他线程通过管道发送消息以取消任何待处理的select和获取select线程重新扫描它应该查看的文件描述符表(使用正确的同步!)并更新自己的fd_set