边缘触发的问题:不必要的唤醒以及饥饿

1)不必要的唤醒:

1.内核:收到第一个连接请求。线程 A 和 线程 B 两个线程都在 epoll_wait() 上等待。

由于采用边缘触发模式,所以只有一个线程会收到通知。这里假定线程 A 收到通知

2.线程A:epoll_wait() 返回

3.线程A:调用 accpet() 并且成功

4.内核:此时 accept queue 为空,所以将边缘触发的 socket 的状态从可读置成不可读

5.内核:收到第二个建连请求

6.内核:此时,由于线程 A 还在执行 accept() 处理,只剩下线程 B 在等待 epoll_wait(),

于是唤醒线程 B。

7.线程A:继续执行 accept() 直到返回 EAGAIN

8.线程B:执行 accept(),并返回 EAGAIN,此时线程 B 可能有点困惑(“明明通知我有事件,结果却返回 EAGAIN”)

9.线程A:再次执行 accept(),这次终于返回 EAGAIN

2)饥饿:

1.内核:接收到两个建连请求。线程 A 和 线程 B 两个线程都在等在 epoll_wait()。

由于采用边缘触发模式,只有一个线程会被唤醒,我们这里假定线程 A 先被唤醒

2.线程A:epoll_wait() 返回

3.线程A:调用 accpet() 并且成功

4.内核:收到第三个建连请求。由于线程 A 还没有处理完(没有返回 EAGAIN),

当前 socket 还处于可读的状态,由于是边缘触发模式,所有不会产生新的事件

5.线程A:继续执行 accept() 希望返回 EAGAIN 再进入 epoll_wait() 等待,

然而它又 accept() 成功并处理了一个新连接

6.内核:又收到了第四个建连请求

7.线程A:又继续执行 accept(),结果又返回成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值