最佳实践是不轮询...但是当线程调用wait()时,轮询是否不会在内部进行?


13

假设我们有一些线程想要检查另一个线程何时完成其任务。我已经读到我们应该调用一个wait()类型的函数,该函数将使该线程等待,直到它收到另一个线程完成的通知。这样做很好,因为这意味着我们不会执行昂贵的轮询。

但是反正不是在内部进行较低级别的轮询吗?也就是说,如果我们使线程wait()是内核不执行轮询来检查另一个线程何时完成,以便它可以随后通知第一个线程?

我想我在这里错过了什么,有人可以启发我吗?

Answers:


28

操作系统为此类进程间通信提供了某些不需要轮询的原语。

如果进程A在互斥锁M上等待,则操作系统会知道A无法运行,并将其放在一堆进程中等待发生的事情。持有M的进程释放后,操作系统会查看等待它的进程列表。列表中的第一个进程(也许是A)将从空闲存储桶中删除,并放入运行队列中。下次A获得时间片时,它调用的wait()将返回,程序继续。


因此以某种方式在操作系统级别进行轮询?
tgkprog 2013年

7
否@tgkprog,这不是轮询,因为在OS或其他进程释放互斥锁之前,不计划运行等待的进程。轮询过程将继续在cpu调度中竞争,以检查它是否应该停止等待。这种轮询过程在等待时会消耗大量CPU时间。
joshp

我的意思是操作系统进程轮询互斥状态。尽管我确信它的优化和超越我们的能力。可能作为调度程序的一部分运行。
tgkprog

4
@tgkprog:在持有互斥量的进程释放它或终止之前,操作系统不会对互斥量进行任何关注。这些事件中的任何一个都将导致OS将互斥锁锁定到等待列表上首先出现的任何进程,并将该进程标记为可运行。没有轮询,只响应事件。joshp所说的所有内容均已包含在参考中。:-)
Blrfl 2013年

2
@csss:差不多。进程可以自愿终止(例如,_exit(2)在POSIX-y系统上调用),也可以自愿终止(例如,诸如被零除之类的错误会产生中断或其他调用kill(2))。无论哪种情况,控制都明确地交还给OS,后者知道正在运行或将终止什么进程。结束进程的工作包括释放其资源,包括互斥量。如果某个互斥锁已被已死的进程占用,则操作系统将释放它。如果该进程在互斥体的等待列表中,它将被删除。
Blrfl 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.