我在使用单选呼叫编写第一个异步服务器时遇到了这个问题:
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会一直等待,直到从客户端收到任何数据。
答案 0 :(得分:2)
当然,您无法在一个线程中修改数据,并且期望在没有正确同步的情况下,修改在其他线程中可见。 select
可能会在被调用时立即读取fd_set
,然后再也不会再查看它;但无论如何,如果已经调用select
,则无法获得必要的同步。你真的需要重新考虑你的设计。一种解决方案是“自管”技巧:打开管道select
始终在寻找输入,让其他线程通过管道发送消息以取消任何待处理的select
和获取select
线程重新扫描它应该查看的文件描述符表(使用正确的同步!)并更新自己的fd_set
。