![有人可以解释一下 Linux 中的睡眠/唤醒动态吗?](https://linux22.com/image/118870/%E6%9C%89%E4%BA%BA%E5%8F%AF%E4%BB%A5%E8%A7%A3%E9%87%8A%E4%B8%80%E4%B8%8B%20Linux%20%E4%B8%AD%E7%9A%84%E7%9D%A1%E7%9C%A0%2F%E5%94%A4%E9%86%92%E5%8A%A8%E6%80%81%E5%90%97%EF%BC%9F.png)
我正在研究操作系统中的锁定机制,并遇到了这些 POSIX 函数:
pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m);
pthread_cond_signal(pthread_cond_t *c);
我完全理解这里睡眠/醒来背后的想法。但我不确定这是如何在硬件中完成的以及它如何影响调度......等
我的理解是,当线程执行: pthread_cond_wait() 时,它会进入睡眠状态(阻塞),但这实际上意味着什么?是的,它被取消调度并进入特权队列中某处的阻塞状态,但是当另一个进程执行 pthread_cond_signal() 时,CPU 如何唤醒阻塞的线程?内核是否在定时器中断期间检查所有条件变量,然后决定唤醒与已释放的线程关联的线程?
我在网上找不到这方面的详细解释,或者也许我看得不正确。
非常感谢任何帮助。
答案1
通过将进程/线程插入要调度的进程/线程队列中来唤醒进程/线程。如果你看一下来源其中signal
,有一个等待条件变量的线程的用户空间列表,其中一个线程被futex
系统调用唤醒。每个刻度检查条件变量数组会非常慢......
因此,当他们描述线程被阻塞时,并不意味着它被放入阻塞队列中,就像等待 I/O 的线程一样?
线程被实现为用户空间和内核空间的混合。就像等待 I/O 的线程/进程被放入内核空间列表中,以便在特定 I/O 操作完成时重新调度一样,等待条件变量的线程也被放入该条件变量的用户空间列表中。所以你的问题的答案是“是和否”。 :-)
并且当前的线程实现多年来一直在优化,因此当实现与(更简单的)原则不匹配时,不要陷入困境。
答案2
当一个线程调用sleep方法时,该线程将被添加到一个睡眠队列中。如果计算时钟频率为100HZ,则意味着每10ms当前运行的进程就会被中断一次。保留线程的当前上下文后,它将为每个线程减少该值(-10ms)。当它为零时,线程将移至“等待CPU”队列。当时间片来到这个线程时,它就会再次运行。也因为这个并没有立即开始运行,所以实际休眠的时间比它设置的值要大。