最近我了解到 Linux 内核中的 Sleep 系统调用会将当前调用线程挂起至 挂起/阻塞 状态,这意味着它们在提到的时间过去之前不会使用 CPU。 - 完全理解。
现在介绍互斥体和信号量,
互斥锁:
acquire() {
while (!available)
; // busy wait --> my doubt
available = false;;
}
release() {
available = true;
}
信号量锁:
wait(S) {
while (S <= 0)
; // busy wait --> my doubt
S--;
}
signal(S) {
S++;
}
P.S:这些代码片段取自 ABRAHAM SILBERSCHATZ 的 “操作系统概念 - 第 9 版”
我的问题:
我知道繁忙等待并不是解决同步问题的有效方法,但是从上面提到的代码片段中我怀疑使用互斥锁和信号量最终会导致繁忙等待?? (尽管互斥体和信号量被广泛用于解决大多数系统问题)。
这反过来让我觉得使用互斥体和信号量并不是解决同步问题的有效方法,因为它会消耗CPU周期(因为它不会导致挂起状态而不是在while循环中旋转).
简而言之:互斥体和信号量是否忙等待而不是将等待线程置于挂起状态??
提前致谢!如果我的理解有错误请指正!!
互斥体和信号量是否忙等待
不,这些函数在内部(例如像
pthread_mutex_lock
这样的Pthread互斥函数)使用atomic机器指令(用汇编程序编码)和futex(7)。
对于 POSIX 信号量(请参阅 sem_overview(7)),内核 scheduler 将安排其他任务。所以不忙等待。
如果没有任务可运行,内核将处于“空闲循环”中,等待(不消耗 CPU 周期)某些事情(例如“中断”)。因此,在这种情况下,您的笔记本电脑不会过热并消耗太多电池! 另请阅读操作系统:三个简单的部分
(可免费下载)。如果你想开发一些玩具内核,也可以看看OSDEV。 您还可以研究 Linux kernel 的源代码,因为它是 free software 然后在 kernelnewbies 上提问。标准 C 库及其 pthread 层也是免费软件(因此请学习 GNU glibc 或 musl-libc 源代码)。 我认为你问题的答案在很大程度上取决于我们正在讨论的互斥锁和信号量的实现方式;
wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
sleep();
}
}