我想要一些关于互斥和信号量的澄清 我的问题是,
答案 0 :(得分:6)
当一个线程试图获取互斥锁上的锁时,如果该互斥锁已经被保持,那么它通常会使用对OS内核的调用来指示它正在等待,然后当前持有该锁的线程解锁时然后它会调用OS内核来唤醒其中一个等待的线程。
这同样适用于信号量,除非它仅在计数减少到零以下时才会阻塞,并且只有当计数增加到零以上时才会唤醒线程。
繁忙的等待是你在等待某事时不阻塞或睡眠的地方,但是在循环中反复轮询,所以处理器总是很忙,但没有做任何有用的事情。
要真正实现忙碌等待,你需要一个原子变量,但POSIX线程不提供这样的东西,所以你不能真正在pthreads中写一个忙等待。最接近的是锁定互斥锁,读取标志,解锁互斥锁,如果未设置标志则循环。这会反复锁定和解锁互斥锁,但不会等待数据准备就绪。在这种情况下,您应该使用条件变量。
通常情况下,如果线程调用类似usleep
之类的东西来暂停其自己的执行一段时间,则表示线程处于休眠状态。这与阻塞相反,它正在等待另一个线程提供的特定信号。
答案 1 :(得分:4)
请看一下: https://stackoverflow.com/a/24582076/3163691
是的,互斥和信号量正在同步内核对象,当线程尝试 获取 时,其中一个如果该对象已被其他线程拥有,则此线程将被置于 sleep 。
正如您已经猜到的,这个 睡眠 是一个至关重要的功能,因为它允许其他线程做更多有用的工作,而不仅仅是“循环/轮询”。
当拥有对象 的线程 时,这些线程的 睡眠 结束。
[ OS计划程序不会将任何执行切片提供给休眠线程]。
将其与锁定& spinlock ,其中一个主题处于“循环/忙碌等待”状态。国家浪费宝贵的CPU时间几乎没有。因此,用户代码中应避免使用自旋锁。请改用关键部分,互斥或信号量!
从上面的链接可以看出,两个对象都是不同的,应该在最合适的上下文中使用。
将互斥锁视为锁定,只允许 一个线程 拥有它。并且它有许多安全属性(所有权,终止通知,递归等)。
并且,将信号量视为锁定,只允许 指定数量的线程 拥有它。但是,它没有互斥锁的许多有用属性。
希望这有帮助。
答案 2 :(得分:0)
这取决于互斥锁的类型(它的支持实现),有些人忙着回退,其他人只会睡眠内核线程对象,然后当互斥锁更新时会被唤醒,有些是混合的两者(Valve的Source引擎使用混合引擎)。它的特性还取决于它需要跨越内核/用户空间障碍的时间和频率,因为有时这可能比仅仅旋转更长时间更昂贵(如果你想要更多地进入旋转与睡眠方面,请参阅this事情)。
互斥锁通常一次用于单线程输入(尽管它们可能支持同一线程的递归输入)。另一方面,信号量一次只允许 n 线程尝试获取它(请参阅此MSDN写入或this比较英特尔写入。)
休眠线程通常意味着它放弃了它的分配计算时间片,直到它准备好被唤醒,并且OS调度程序给它另一个时间片。您可能会发现的最佳示例实际上是在Linux内核源代码(或任何其他开源操作系统)。
答案 3 :(得分:0)
- 当线程试图进入由互斥锁锁定的区域时,互斥锁实际上做了什么。它等待锁被释放?或b。它去了 睡觉直到锁被释放。在那种情况下它是如何再次醒来的 当锁被释放?
醇>
当线程尝试获取互斥锁时,它会被卡住并仅在锁定被授予该线程时返回。锁被操作系统识别,因此操作系统知道,直到这样的锁可用于提供线程 - 它没有别的办法。线程停在OS内部。只有操作系统知道现在线程拥有所有权才会重新入睡。在单CPU系统中,如果某个其他进程处于打开状态,则只有当线程同时具有两者时,互斥锁才会返回 - CPU可用以及授予锁定!
注意:当您执行fwrite
或select
同样的事情时。由于OS知道相应的IO将花费时间,因此线程变为空闲。当数据到达时,线程变为可运行。
- 与1相同的问题,但在这种情况下它是信号量。你能给我一些关于在C中忙于等待pthread的代码,还有一个案例 线程进入睡眠而不是等待?睡觉意味着它 阻塞或睡觉是另一种忙碌的等待?
醇>
在这两种情况下,都没有忙碌的等待。如果任何人忙着等待你的时间来锁定时间 - 你实际上没有锁定的目的!考虑一下,假设我们有严格的单CPU案例(和一个愚蠢的操作系统)。所以会发生什么,线程1尝试获取锁,因为锁位于线程B,因此线程A开始忙等待。因此,CPU永远不会从线程A释放,线程B永远不会在CPU上执行 - 最终两个线程都处于无用状态。锁对线程对象没有任何作用。但锁定过程总是停留线程
答案 4 :(得分:0)
等待,睡觉,阻止,都意味着同样的事情:
线程进行系统调用(获取互斥锁或信号量,等待一段时间,无论如何)
操作系统获得控制权,运行调度程序,将线程标记为等待资源,同时更新其他线程的状态,然后控制准备运行的线程。如果准备好运行多个线程,则根据调度策略选择一个。
一旦资源可用(通过另一个线程进行的另一个系统调用),调度程序就会将前一个线程的状态更新为等待资源准备好运行,并且线程被赋予控制权一旦调度程序策略决定如此。
只要线程正在等待资源,它就不会占用CPU。没有民意调查。
答案 5 :(得分:-1)
简单来说,当你关注1个锁时,Mutex是用来做东西的....信号量用于多个锁... 我会尽力寄给你样品。我记得我在C中有一些与信号量和互斥量有关的任务。 就概念而言,这是有趣的http://geekswithblogs.net/shahed/archive/2006/06/09/81268.aspx:)
由于