【问题标题】:If a mutex is already locked how can pthread_mutex_lock(pthread_mutex_t *mutex); block the thread and still return a value at the same time?如果互斥锁已被锁定,如何 pthread_mutex_lock(pthread_mutex_t *mutex);阻塞线程并同时返回一个值?
【发布时间】:2021-11-08 21:44:06
【问题描述】:

mutex 引用的互斥对象应通过调用pthread_mutex_lock() 来锁定。如果互斥锁已被锁定,则调用线程应阻塞,直到互斥锁可用。此操作应返回 mutex 所引用的互斥对象,该对象处于锁定状态,调用线程为其所有者。

我的问题是,如果互斥体已经被锁定,并且我们调用pthread_mutex_lock(),这个函数是在线程被阻塞的情况下返回一个值,还是在阻塞之后返回值?

我的问题的说明。

  • Mutex 被第一个线程锁定。

  • 第二个线程尝试使用pthread_mutex_lock() 锁定此互斥体。

会发生什么? pthread_mutex_lock() 什么时候将其值返回给第二个线程?

是在第一个线程解锁互斥锁之后吗?或者,它是否返回它的值然后阻塞第二个线程?

【问题讨论】:

  • 不加锁就不会被阻塞,第一个线程跑到互斥锁中就是这样。只有下一个线程会阻塞(直到第一个线程释放互斥锁)
  • 函数阻塞直到互斥锁可用,然后返回锁定状态的互斥锁句柄。在解除阻塞之前它不会返回。
  • @DanielFarrell 当第二个线程试图锁定这个锁定的互斥体时,pthread_mutex_lock() 只会在互斥体解锁时返回一个值,对吧?
  • @African_king pthread_mutex_lock() 等到互斥锁被解锁,然后锁定它,然后向调用者返回一个值
  • 是的,这就是可观察到的效果。不过,这不是一个忙碌的等待!在互斥锁解锁之前,被互斥锁“停止”的线程不会消耗任何 CPU 周期。

标签: c++ c pthreads mutex


【解决方案1】:

对您的问题的简短回答:pthread_mutex_lock(&mutex) 不会返回值,直到线程在获得锁后解除阻塞。但是,您的代码只看到一个函数调用并感知一个直接返回值。

这里有更多解释。

关于返回值:

  • 如果函数 pthread_mutex_lock(&mutex) 返回零,您可以相信您的线程已锁定 mutex:别忘了解锁它!

  • 如果该方法返回non-zero error code,则互斥锁未被您的线程锁定,您不应进行相应的解锁。

你的代码调用的视角pthread_mutex_lock(&mutex)

  • 如果 mutex 未被锁定,pthread_mutex_lock(&mutex) 将锁定 mutex 并立即返回零。

  • 如果 mutex 已经被另一个线程锁定,该函数将阻塞,直到您的线程获得 mutex 上的锁定,然后返回零。但是,从代码的角度来看,您只会看到一个返回值的函数调用:线程中的代码不会注意到它被阻塞了。当然,除非您在函数调用周围放置计时器。

  • 如果 mutex 已经被你的线程锁定,函数就会死锁。默认情况下,互斥锁是不可重入的,您必须避免将其锁定在已经锁定的上下文中,例如递归。 我把它放在了如何做重入锁定的范围之外。在这种情况下,函数永远不会返回。

  • 如果 mutex 由于任何原因无法锁定,该函数会立即返回 non-zero error code

【讨论】:

    【解决方案2】:

    该描述意味着该函数将阻塞,直到互斥锁(由其先前的所有者)解锁,然后它锁定互斥锁,并且只有在此之后才返回。现在,函数的调用者是锁的所有者。

    【讨论】:

    • 当第二个线程试图锁定这个被锁定的互斥体时,pthread_mutex_lock() 只会在互斥体解锁时返回一个值,对吧?
    • @African_king 不,那没用。该函数将在返回之前锁定互斥锁。
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 2013-01-15
    • 2010-12-26
    • 1970-01-01
    • 2019-08-20
    • 2012-12-25
    • 1970-01-01
    • 2021-11-25
    相关资源
    最近更新 更多