繁体   English   中英

操作系统事件/信号/等待句柄的实现

[英]Operating System Implementation of events/signals/wait handles

出于好奇,我想知道操作系统如何实现等待事件/句柄等的唤醒线程。

例如,假设OS线程不断扫描等待句柄列表,并在必要时执行相应的线程。 并不是说我相信它以这种方式实现,因为它似乎效率低下。

我认为操作系统更有可能在包含与暴露的等待句柄/事件相关的同步原语的内存区域设置硬件中断,然后当它们被触发时,它可以小心地安排线程而不是多次安排它?

编辑

实际上我想更具体地说是我想要考虑的但是并没有完全找到了唤醒睡眠核心来运行阻塞线程的根本原因?

为了更详细地理解它,你必须学习操作系统课程(或者至少购买一本关于这个主题的好书),因为它实际上涉及很多系统。

然而,基本上,它涉及如何管理线程状态。 线程是任何时候的几种不同状态之一:睡眠,准备或运行(通常更多,但这就是本讨论所需的全部内容)。 处于运行状态的线程实际上正在运行,并且线程中的代码正在执行。 处于“休眠”状态的线程未运行,并且在决定下一个运行时,调度程序将跳过它。 处于“就绪”状态的线程当前没有运行,但是一旦另一个线程进入休眠状态或它的时间片耗尽,调度程序可以自由选择安排该线程进入运行状态。

所以基本上,当你在互斥对象上调用“wait”时,操作系统会检查对象是否已经被另一个线程拥有,如果是,则将当前线程的状态设置为“休眠”,并将该线程标记为“等待”特别是互斥。

拥有互斥锁的线程完成后,操作系统将遍历等待它的所有线程,并将它们设置为“就绪”。 调度程序下次出现时,它会看到一个“就绪”线程并将其置于“运行”状态。 线程开始运行并检查它是否可以再次锁定互斥锁。 这次没有人拥有它,所以它可以继续它的快乐方式。

实际上,它要复杂得多,并且需要付出很多努力才能使系统尽可能高效(例如,避免唤醒线程只是让它立即恢复睡眠,以避免线程挨饿在一个有很多其他线程等待它的互斥锁上,等等)

介绍性的教科书答案是,当一个线程等待事件发生时,它会被放到一个等待线程的队列中。 该线程被标记为“等待”,因此操作系统的进程调度程序在查找要在处理器上运行的内容时会跳过该线程。 最终(在正确的程序中),另一个线程将唤醒正在等待事件队列的一个或所有线程。 然后线程被标记为“就绪”,OS开始再次调度它们。

当然,实际实现的方式相当棘手。 我认为这是你真正的问题。 对于Linux,你正在寻找的机制被称为futex ,它们对我来说太复杂了,在这里做正义。 如果Wikipedia模糊了你的兴趣,请深入了解wiki页面底部的那些外部链接。

我相信实现更简单,一个线程放在一个等待线程列表中(所有线程都在等待某个事件/句柄/互斥锁等等。当同步原语被唤醒时,所有线程都被移动到运行状态并且列表已清理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM