想到个问题,异步一般是用来处理网络 io,文件 io 或者睡眠这三类需求,前两类需求比较好理解,将文件描述符交给 epoll 监听,无反馈时阻塞整个程序,有反馈时就执行事件循环逻辑,思路很清晰。但是睡眠这个是怎么实现的呢,睡眠又没有个什么描述符指向
|
araaaaApr 21, 2021 via iPhone
1
一般会用时间轮
|
|
MohansonApr 21, 2021 via Android
2
RTFD
|
|
pabupaApr 21, 2021 via Android
3
主循环除了处理 io,还有一个 timeout 的堆,和一个 callback 的链表。
sleep 就是加一个 timeout 。 |
|
codehzApr 21, 2021 via Android
4
可以有 timerfd 来着的,不过似乎大家都是自己用 epoll 的超时机制实现,毕竟文件句柄多了对性能也有影响的(
|
|
soulzzApr 21, 2021
5
|
|
6
@pabupa 问题是如果 timeout 和 epoll 是两个东西,那一个循环怎么同时监听这两个呢。。比如它清空了 epoll 任务,那就阻塞在 epoll 上了,这时候如果 timeout 发生了,但线程又不能唤醒自己
|
|
sujin190Apr 21, 2021
7
@LeeReamond #6 epoll 等待的时候可以设置一个等待超时时间,然后把下一个 timer 超时的时间设置为 epoll 等待超时的时间就行了,epoll 超时返回不会给出任何 fd,所以啥也不干去检查是否有 timer 超时就好了
|
|
8
@sujin190 感谢回复,是一种可行解决方案,大概就是楼上说的 epoll 机制的那种解法吧,根据楼上回复似乎还有其他方案。不过这样又叫人好奇起来 epoll 的超时是怎么实现的,神奇的计算机系统啊
|
|
pabupaApr 21, 2021
9
@LeeReamond #6 epoll 也可以立即返回啊。
当 timeout 和 callback 都为空时,再阻塞调用。有一个不为空,就立即返回。 |
|
pabupaApr 21, 2021
10
|
|
3dwelcomeApr 21, 2021
11
Windows 才是异步编程的鼻祖,当年 JS 陷入回调地狱的时候,Windows 消息机制把所有函数都变成消息收发事件,把代码逻辑安排井井有条,一个 case 对应一个任务。
epoll 超时应该也是抄这种模式,调用后就阻塞,只有被外界消息触发后,才会返回一个结果。 |
|
3dwelcomeApr 21, 2021
12
@LeeReamond "比如它清空了 epoll 任务,那就阻塞在 epoll 上了,这时候如果 timeout 发生了,但线程又不能唤醒自己"
所谓阻塞应该只是把自己线程的 context 挂起,又不会写个死循环傻等。。 然后等内核的中断消息来触发线程复原。消息可以是时间或者 socket 收发事件。 |