请问编程语言中阻塞机制在操作系统最底层是如何实现的?

2019-12-26 10:24:51 +08:00
 squancher

首先大致问题如上,有以下两个疑问

  1. 有一种说法是程序阻塞不占用 CPU 资源。根据我所查阅到的资料,JAVA 为例,阻塞机制最后都到了 native 方法,也就是 C 语言实现,调用到了操作系统的方法(这个说法有点不准确),然后是关于 Linux 阻塞队列的原理,有一个 __wait_event 方法,具体如下:
#define __wait_event(wq, condition)
       do {
               DEFINE_WAIT(__wait);

               for (;;) {
                       prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);
                       if (condition)
                               break;
                       schedule();
               }
               finish_wait(&wq, &__wait);
       } while (0)

然后就没有其它资料了,可以看到里面有一个死循环,所以底层是会用循环来判断是否满足条件?(感觉并没有到底层)那么这也是变相消耗系统资源了啊,有点像回调
2. 如果底层是使用循环来判断,那么例如定时器,操作系统是如何管理时间的?如果也是有循环,那么时间粒度是多少,1 毫秒?如果不是,如何判断时间到达?

感觉最底层一定不是我所猜测的这样,应该是有特殊的数据结构和方法。最后,不要说什么操作系统内核完成,我就是想学习一下原理,就算是汇编也想研究下,有懂的大佬能解下惑吗?或者给几个相关技术名词。

7705 次点击
所在节点    程序员
80 条回复
squancher
2019-12-26 13:20:19 +08:00
有点晕了,就能简单说一下定时器吗,Java 定时器 timer,我设定一个时间,操作系统怎么判断时间到了没有,是每毫秒检查一次还是?
zjsxwc
2019-12-26 13:23:22 +08:00
通过 中断、事件、tick 等方式让操作系统调度呗
squancher
2019-12-26 13:23:58 +08:00
@zjsxwc 这又绕回来了
zwhfly
2019-12-26 13:26:30 +08:00
@squancher 算出目标时间点发给硬件时钟,硬件时钟到时间给 CPU 发中断信号啊。
codehz
2019-12-26 13:26:54 +08:00
@squanche 内核也有线程,定时器会专门开一个线程管理,然后他就可以做一个操作:依次排列各个定时器事件,循环检查第一个定时器有没有触发,然后循环内每次检查后都主动放弃执行绪切到另一个内核线程处理别的事务(
squancher
2019-12-26 13:28:39 +08:00
再拿人举个例子,我现在让另一个人一个小时后通知我一声,然后我要睡觉了,一直等待(中断),但是另一个人开始工作,要么一分钟看下时间,要么五分钟看下时间,时间差不多了就唤醒。
wamson
2019-12-26 13:29:24 +08:00
@squancher。。。想这么复杂干什么,其实就是 cpu 在每个时钟周期都会去检测某个引脚的电平是高电平还是低电平(这个电平是别的硬件电路传递过来的,比如 IO 事件一般是 DMA 控制器),如果是高电平则表示有中断信号到达,就会保存现场,然后跳去执行中断处理函数,完了恢复现场。
详细请参考<操作系统>,或者看一下<ucos ii 源码>
zwhfly
2019-12-26 13:29:55 +08:00
@squancher 你对“中断”的理解是错误的。
zwhfly
2019-12-26 13:31:36 +08:00
中断是 CPU 的一个动作,而不是一个状态。中断是“状态转换”这个动作。
squancher
2019-12-26 13:36:22 +08:00
好吧,综上所述,有人能做个总结吗,这种“判断、检查”是否是快速循环检测,比如按照机器周期的频率,然后这个循环时间粒度可控吗?
codehz
2019-12-26 13:36:56 +08:00
其实不去实现操作系统也不是不能了解这个阻塞调用机制
你可以自己实现一个协程
然后看看不使用系统调用的情况下如何实现 timer
(是不是只能一个死循环,最多优化优化检查策略)
然后我这里就做了一个模仿操作系统的协程模型 https://github.com/codehz/ctxco
其中 poller 函数可以理解为系统调用的处理函数(然后自己实现如何将请求异步提交给系统,并返回调度具体协程)
zwhfly
2019-12-26 13:37:24 +08:00
对于 CPU 来说,中断是跳到另一段程序执行,而不是等待。但对中断前那段代码来说,由于被跳走了,所以逻辑上这段程序在等待,等待操作系统什么时候操纵 CPU 再跳回来。但 CPU 一直是有事干的,从来不闲着,最闲的时候也是循环执行 pause 指令(x86)。
caowentao
2019-12-26 13:42:36 +08:00
楼主一开始的理解就没有问题,只是对结论持怀疑态度
justRua
2019-12-26 13:47:43 +08:00
https://www.zhihu.com/question/20785028/answer/378615520
之前在知乎上看到过类似问题,底层也是轮询
nevin47
2019-12-26 13:48:41 +08:00
@squancher 47 楼讲的很清楚了

另外如果真的想系统理解,最好配合计算机组成原理和现代操作系统两本书看看。只言片语得理解很容易搞成民科了,你这个问题是软硬件领域的交界,以纯软件的思维去理解是偏的
squancher
2019-12-26 13:50:17 +08:00
这个问题困扰我很久了,就算硬件时钟给 CPU 发中断信号,硬件时钟同样得做时间判断,所以一句话就是能不能不通过循环,机器周期这些方法,有特殊的算法实现
smdbh
2019-12-26 13:50:49 +08:00
盲狙 wfe()
ccpp132
2019-12-26 13:52:28 +08:00
主要是硬件有中断机制,从这点出发其实没太大问题。光从软件上来理解是很难的。
GeruzoniAnsasu
2019-12-26 13:54:20 +08:00
@squancher 所以说了,没有。你看起来的“实时” 就 就 就是先把状态改了等下一个时间片而已

下一个时间片分不到定时器就是不准的。就这样。
ccpp132
2019-12-26 13:55:19 +08:00
@squancher 硬件时钟可以独立于 cpu 做循环,不影响 cpu 就行了啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/632449

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX