我正处于游戏场景中。服务器和客户端都通过非阻塞UDP以高速率交换消息。
(这里可能很奇怪......)遗留代码也使用select(),超时值设置为0,这意味着select()不会阻塞。 Select()在一个永远的while循环中。 select()返回一个大于0的数字,代码通过recvfrom()接收消息。如果它返回0,则以下代码不会尝试接收。
从打印输出信息中,我看到select()有时会返回1(大于0)。我很困惑,因为超时设置为0,select()有时间检查消息是否准备好从任何readfds读取?谢谢。
答案 0 :(得分:1)
根据the spec:
成功完成后,pselect()或select()函数应该 修改readfds,writefds和errorfds指向的对象 用于指示哪些文件描述符可供读取的参数, 准备写入,或者分别有待处理的错误条件, 并且应该返回所有的准备描述符的总数 输出集。对于每个小于nfds的文件描述符, 如果成功完成,则应设置相应的位 在输入上设置,并且该文件的关联条件为true 描述符。
如果所选描述符都没有为请求的操作做好准备,则pselect()或select()函数将阻塞,直到至少有一个请求的操作准备就绪,直到超时发生,或直到被中断为止信号。超时参数控制pselect()或select()函数在超时之前需要多长时间。如果timeout参数不是空指针,则它指定等待选择完成的最大间隔。如果指定的时间间隔到期而没有任何请求的操作准备就绪,则该函数应返回。如果timeout参数是空指针,则对pselect()或select()的调用将无限期地阻塞,直到至少一个描述符满足指定的条件。 要实现轮询,timeout参数不应该是空指针,而应指向零值timespec结构。
简而言之,在检查超时之前检查描述符。如果在调用select()
时套接字已准备好数据,则忽略超时并立即退出select()
。