1
araaaa 2021-04-21 07:49:50 +08:00 via iPhone
一般会用时间轮
|
2
Mohanson 2021-04-21 07:56:23 +08:00 via Android
RTFD
|
3
pabupa 2021-04-21 08:23:00 +08:00 via Android
主循环除了处理 io,还有一个 timeout 的堆,和一个 callback 的链表。
sleep 就是加一个 timeout 。 |
4
codehz 2021-04-21 08:24:55 +08:00 via Android
可以有 timerfd 来着的,不过似乎大家都是自己用 epoll 的超时机制实现,毕竟文件句柄多了对性能也有影响的(
|
5
soulzz 2021-04-21 08:31:38 +08:00
|
6
LeeReamond OP @pabupa 问题是如果 timeout 和 epoll 是两个东西,那一个循环怎么同时监听这两个呢。。比如它清空了 epoll 任务,那就阻塞在 epoll 上了,这时候如果 timeout 发生了,但线程又不能唤醒自己
|
7
sujin190 2021-04-21 09:49:43 +08:00
@LeeReamond #6 epoll 等待的时候可以设置一个等待超时时间,然后把下一个 timer 超时的时间设置为 epoll 等待超时的时间就行了,epoll 超时返回不会给出任何 fd,所以啥也不干去检查是否有 timer 超时就好了
|
8
LeeReamond OP @sujin190 感谢回复,是一种可行解决方案,大概就是楼上说的 epoll 机制的那种解法吧,根据楼上回复似乎还有其他方案。不过这样又叫人好奇起来 epoll 的超时是怎么实现的,神奇的计算机系统啊
|
9
pabupa 2021-04-21 11:33:56 +08:00
@LeeReamond #6 epoll 也可以立即返回啊。
当 timeout 和 callback 都为空时,再阻塞调用。有一个不为空,就立即返回。 |
10
pabupa 2021-04-21 11:39:04 +08:00
|
11
3dwelcome 2021-04-21 12:14:16 +08:00
Windows 才是异步编程的鼻祖,当年 JS 陷入回调地狱的时候,Windows 消息机制把所有函数都变成消息收发事件,把代码逻辑安排井井有条,一个 case 对应一个任务。
epoll 超时应该也是抄这种模式,调用后就阻塞,只有被外界消息触发后,才会返回一个结果。 |
12
3dwelcome 2021-04-21 12:22:36 +08:00
@LeeReamond "比如它清空了 epoll 任务,那就阻塞在 epoll 上了,这时候如果 timeout 发生了,但线程又不能唤醒自己"
所谓阻塞应该只是把自己线程的 context 挂起,又不会写个死循环傻等。。 然后等内核的中断消息来触发线程复原。消息可以是时间或者 socket 收发事件。 |