开发者社区> 问答> 正文

IO多路复用是否会遗漏IO事件?

这个问题如果完整贴代码可能会比较长,所以只简单说一下。
Test1是一个简单的成功的例子:
server端代码大概如下:

set up a listenfd
while (1) {
    if (select(listenfd) > 0) {
        if (FD_ISSET(listenfd)) {
            accept new clientfd
            read clientfd
            write clientfd
            close clientfd
        }
    }
}
client端代码大概如下:

while (1) {
    set up a clientfd
    write something to server
    read something from server
    output them to console
}
这里是没什么问题的,两个进程无限跑。client会先sleep1秒,等一下server。

Test2改成下面这种更加复杂一点的模式时就卡住了,先看代码:
server端:

set up a listenfd
while (1) {
    if (select(readset, writeset) > 0) {
        foreach(fd in readset) {
            if (fd == listenfd) {
                accept new clientfd
                add clientfd to readset
            } else {
                /*this is a clientfd accepted before*/
                read fd
                remove fd from readset
                add fd to writeset
            }
        }
        foreach(fd in writeset) {
            /*this is a clientfd accepted and readed before*/
            write fd
            remove fd from writeset
            close fd
        }
    }
}
client端:

while (1) {
    set up a clientfd
    write something to server
    read something from server
    output them to console
}

//exactly same as before
client端没有改动,server端将accept之后的动作分开重新交给select去监听。
程序运行的时候是卡住的,我调式也一直卡在select处。
我推测是server端的listenfd在accept到一个clientfd,将该clientfd加入readset的这一过程中,
client端中的fd已经read结束了,因此server端select没有监听到该事件,然后client端在等待server的write,而server在等待client的read?
完整代码地址:
https://github.com/zhaochenyou/tips/blob/master/c/socket/server/select.c

展开
收起
a123456678 2016-06-23 14:14:10 1768 0
1 条回答
写回答
取消 提交回答
  • elect不指定超时时间

    2019-07-17 19:46:13
    赞同 展开评论 打赏
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
多IO线程优化版 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载