P b*_*sak 9 c multithreading mutex semaphore pthreads
我想要一些关于互斥和信号量的澄清.
我的问题是,
当一个线程试图获取互斥锁上的锁时,如果该互斥锁已被保持,那么通常它将使用对OS内核的调用来指示它正在等待,然后当当前持有锁的线程解锁互斥锁然后它将调用OS内核来唤醒其中一个等待的线程.
这同样适用于信号量,除非它仅在计数递减到零以下时才会阻塞,并且只有当计数增加回到零以上时才会唤醒线程.
忙碌的等待是在等待某些事情时不会阻塞或睡眠的地方,但是在循环中反复轮询,因此处理器总是很忙,但没有做任何有用的事情.
要真正实现忙碌等待,您需要一个原子变量,但POSIX线程不提供这样的东西,因此您无法在pthreads中真正编写忙等待.最接近的是锁定互斥锁,读取标志,解锁互斥锁,如果未设置标志则循环.这会反复锁定和解锁互斥锁,但不会等待数据准备就绪.在这种情况下,您应该使用条件变量.
通常情况下,如果某个线程已调用类似于usleep在指定时间段内暂停其自身执行的内容,则表示该线程处于休眠状态.这与阻塞相反,它在等待由另一个线程提供的特定信号.
请看:https : //stackoverflow.com/a/24582076/3163691
是的,互斥体和信号量都在同步内核对象,当一个线程尝试获取其中一个对象时,如果该对象已被其他线程拥有,则该线程将进入睡眠状态。
正如您已经猜到的,这种休眠是一个至关重要的特性,因为它允许其他线程做比“循环/轮询”更有用的工作。
该睡觉的一个这些线程结束的时,谁拥有对象的线程释放它。
[ OS Scheduler不会为休眠线程提供任何执行切片]。
将其与锁和自旋锁进行对比,其中线程处于“循环/忙等待”状态,浪费宝贵的 CPU 时间,几乎什么都不做。因此,应避免在用户代码中使用自旋锁。改用临界区、互斥锁或信号量!。
正如您从上面的链接中看到的,这两个对象是不同的,应该在最适合的正确上下文中使用。
将互斥锁视为只允许一个线程拥有它的锁。并且它具有许多安全属性(所有权、终止通知、递归等)。
并且,将信号量视为只允许指定数量的线程拥有它的锁。但是,它没有mutex的许多有用属性。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
15266 次 |
| 最近记录: |