【问题标题】:What does mutex and semaphore actually do?互斥量和信号量实际上是做什么的?
【发布时间】:2012-03-14 16:45:15
【问题描述】:

我想澄清一下关于互斥锁和信号量的问题。
我的问题是,

  1. 当线程试图进入被互斥锁锁定的区域时,互斥锁的实际作用是什么? 一种。它等待锁被释放? 或 b。它进入睡眠状态,直到锁被释放。那么锁释放后如何再次唤醒呢?
  2. 与 1 相同的问题,但在本例中是信号量。
  3. 你能给我一些关于 C 中 pthread 中忙等待的代码,以及线程进入睡眠而不是等待的情况吗? sleep 是否意味着它被阻塞或 sleep 是另一种忙等待?
  4. 我想知道一些涵盖这种情况的程序,例如一些实现忙等待、阻塞等的c源代码。

【问题讨论】:

  • 不,我了解了线程同步的忙等待和阻塞机制。但我不确定互斥量和信号量的作用。

标签: c multithreading pthreads mutex semaphore


【解决方案1】:

请看: https://stackoverflow.com/a/24582076/3163691

是的,mutexsemaphore 都在同步内核对象,当线程尝试获取其中之一时他们,如果该对象已被其他线程拥有,则该线程将进入 sleep

正如您已经猜到的那样,这个睡眠是一个至关重要的功能,因为它允许其他线程做比“循环/轮询”更有用的工作。

一个线程的睡眠在拥有对象的线程释放它。

[OS Scheduler 不会将任何执行 slice 分配给 sleeping threads]。

将其与 lockspinlock 进行对比,其中线程处于“循环/忙碌等待”状态,浪费宝贵的 CPU 时间几乎什么都不做强>。因此,在用户代码中应避免自旋锁。请改用临界区mutex信号量

从上面的链接可以看出,这两个对象是不同的,应该在最适合的正确上下文中使用。

mutex 视为一个 ,它只允许 一个线程 拥有它。并且它具有许多安全属性(所有权、终止通知、递归等)。

并且,将 信号量 视为 ,它只允许 指定数量的线程拥有它。但是,它没有 mutex 的许多有用属性。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    等待、休眠、阻塞,都是同一个意思:

    1. 线程进行系统调用(获取互斥锁或信号量,等待一段时间,无论如何)

    2. 操作系统取得控制权,运行调度程序,将线程标记为等待资源,同时更新其他线程的状态,然后将控制权交给准备好运行的线程。如果有多个线程准备好运行,则根据调度策略选择一个。

    3. 一旦资源可用(通过另一个线程进行的另一个系统调用),调度程序将前一个线程的状态从等待资源更新为准备好运行,并且线程被授予控制权一旦调度器策略决定这样做。

    只要线程在等待资源,它就不会消耗 CPU。它的部分没有轮询。

    【讨论】:

      【解决方案3】:
      1. 当线程试图进入一个被互斥锁锁定的区域时,互斥锁的实际作用是什么?它等待锁被释放?或 b。它去 休眠直到锁被释放。那样的话怎么又醒了 什么时候释放锁?

      当一个线程试图获取一个互斥锁时,它会被卡住并且只有当锁被授予该线程时才返回。锁被操作系统识别,所以操作系统知道直到这样的锁可用于给线程 - 它没有别的事可做。线程停在操作系统内部。只有操作系统知道现在线程拥有所有权,它会重新进入睡眠状态。在单 CPU 系统中,如果某个其他进程处于打开状态,则互斥锁仅在线程同时具有这两者时才会返回 - CPU 可用以及已授予锁!

      注意:当您执行fwriteselect 时,会发生同样的事情。由于操作系统知道相应的 IO 需要时间,因此线程变得空闲。当数据到达时,线程变为可运行的。

      1. 与 1 相同的问题,但在本例中是信号量。你能给我一些关于 C 中 pthread 中忙等待的代码吗,还有一个案例 线程在哪里进入睡眠而不是等待?睡眠是否意味着它是 阻塞或休眠是另一种忙等待?

      在这两种情况下,都没有忙等待。如果有人忙着等着打发时间直到你得到锁——你实际上没有达到锁的目的!考虑一下,假设我们有严格的单 CPU 情况(和一个愚蠢的操作系统)。所以发生的事情是,线程 1 尝试获取锁,因为锁在线程 B 上,所以线程 A 开始忙等待。因此,CPU 永远不会从线程 A 释放,线程 B 永远不会有机会在 CPU 上执行 - 最终两个线程都处于无用状态。锁不对线程对象做任何事情。但是锁定过程总是会停止线程

      【讨论】:

      • 嗨,好吧,那么你的意思是如果需要一些旋转,我必须明确地实现那个忙等待,即使用一些变量或条件变量对吗?我的意思是互斥量和信号量不允许线程等待,对吧?例如,如果一个信号量初始化为 5,那么当它为 5 时,其他线程只会被操作系统置于睡眠状态,直到信号量从 5 减少,然后线程将被操作系统唤醒,对吗?
      • @Pbasak 一旦线程获得互斥锁的访问权(或者如果满足信号量条件),线程现在是runnable - 系统中可能有许多可运行线程,因此取决于其他方面操作系统调度。互斥量获取本身不会控制系统中的其他线程 - 但您的号码现在处于活动队列中。
      【解决方案4】:

      这取决于互斥体的类型(它的支持实现),有些忙于回退,其他人只会休眠内核线程对象,然后当互斥体更新时将其唤醒,有些是混合两者(Valve 的 Source 引擎使用混合引擎)。它的特性还取决于它需要跨越内核/用户空间障碍的时间和频率,因为有时这可能比仅仅旋转一段时间更昂贵(如果你想更多地了解事物的旋转与睡眠方面,请参阅this )。

      互斥锁通常一次用于单线程条目(尽管它们可能支持同一线程的递归条目)。另一方面,信号量一次只允许 n 个线程尝试获取它(请参阅此MSDN 文章或this 比较英特尔文章)。

      休眠一个线程通常意味着它放弃它的分配计算时间片,直到它准备好被唤醒并且操作系统调度程序给它另一个时间片。您可能会找到的最佳示例实际上是在 linux 内核源代码(或任何其他开源操作系统)中。

      【讨论】:

      • 嗨,我对 linux C 中的 posix 线程实现特别感兴趣。那么,从 posix 的角度来看,互斥锁和信号量实际上是做什么的?例如,如果我在 C 中编写代码,其中一些共享数据被互斥锁锁定,当其他线程访问时,它会等待吗?还是只是阻止释放其资源?以及在信号量的情况下会发生什么。如果线程阻塞,那么在 posix C 中如何实现旋转和忙等待?条件变量是唯一的方法吗?
      【解决方案5】:

      当一个线程试图获取一个互斥锁上的锁时,如果该互斥锁已经被持有,那么通常它会使用对操作系统内核的调用来指示它正在等待,然后当当前持有锁的线程解锁时互斥体然后它将调用操作系统内核以唤醒其中一个等待线程。

      这同样适用于信号量,只是它只会在计数减到零以下时阻塞,并且只有在计数增加到零以上时才会唤醒线程。

      忙等待是指您在等待某事时不会阻塞或休眠,而是在循环中反复轮询,因此处理器总是很忙,但没有做任何有用的事情。

      要真正实现忙等待,你需要一个原子变量,但 POSIX 线程不提供这样的东西,所以你不能真正在 pthreads 中编写忙等待。您可以获得的最接近的方法是锁定互斥锁,读取标志,解锁互斥锁,如果未设置标志则循环。这会反复锁定和解锁互斥锁,但不会等待数据准备好。在这种情况下,您应该改用条件变量。

      通常,如果一个线程调用了类似usleep 的东西来暂停它自己的执行一段指定的时间,你就说它正在休眠。这与阻塞相反,阻塞是等待另一个线程提供的特定信号。

      【讨论】:

      • "然后它将调用 OS 内核以唤醒其中一个等待线程。"那么这是否意味着线程在等待互斥锁解锁或信号量值减小时实际上处于休眠状态?他们没有在后台等待特定的时间吗?
      • 如何处理是操作系统的实现细节,但是是的,等待线程通常不会消耗任何 CPU。它被操作系统添加到等待线程列表中,并且只有在互斥锁被解锁时才被唤醒。
      • 你可以使用pthreads实现忙等待,这就是为什么有pthread_spin_{init,destroy,lock,unlock,trylock}函数。
      • 嗯,我有点理解。我需要知道 pthread 中忙等待的概念。现在看来,程序员需要自己实现忙等待或自旋。然后由他们决定是否要通过引入忙等待来消耗cpu资源。
      • @P basak,实际上有很多库提供内置自旋互斥锁,例如待定。
      【解决方案6】:

      简单来说,互斥锁适用于您关心 1 个锁的东西..信号量适用于多个锁.. 我会尽量把样品寄给你。我记得我有一些与 C 中的信号量和互斥锁相关的作业。 就概念而言,这很有趣http://geekswithblogs.net/shahed/archive/2006/06/09/81268.aspx :)

      谢谢

      【讨论】:

      • 信号量也可以用于单锁。
      猜你喜欢
      • 2011-06-24
      • 2020-04-05
      • 2011-04-20
      • 2011-01-20
      • 2010-10-20
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      相关资源
      最近更新 更多