【问题标题】:Threads trying to acquire pthread_mutex_lock(&mutex) What happens if they don't get the lock?试图获取 pthread_mutex_lock(&mutex) 的线程如果没有获得锁会怎样?
【发布时间】:2011-07-13 04:11:40
【问题描述】:

C 编程:

当线程尝试获取互斥锁但未能获取时会发生什么?

它会睡觉吗?

pthread_mutex_unlock(&mutex); 时会不会唤醒线程?叫什么?

然后再尝试获取锁?

【问题讨论】:

    标签: c pthreads mutex locks


    【解决方案1】:

    来自man page

    pthread_mutex_lock() 函数锁定mutex。如果互斥锁已被锁定,则调用线程将阻塞,直到互斥锁可用。

    所以是的 - 你的线程被阻塞,直到锁可用并且它可以获得它。

    【讨论】:

    • 谢谢。这回答了我的问题。
    【解决方案2】:

    是的,它是一个阻塞调用,并且会阻塞直到它获得锁。

    非阻塞版本是pthread_mutex_trylock(pthread_mutex_t *mutex),如果其他人有锁,则返回EBUSY,如果有锁,则返回0。 (当然也可以是其他错误)

    【讨论】:

      【解决方案3】:

      通常,pthread_mutex_lock 在获得锁之前无法返回,即使这意味着它永远不会返回(死锁)。不过也有一些值得注意的例外:

      • 对于递归互斥体,如果超出最大引用计数,它可以返回EAGAIN
      • 对于错误检查互斥锁,如果线程尝试锁定它已经持有锁的互斥锁,它可以返回 EDEADLK
      • 对于健壮的互斥锁,如果另一个进程在持有(共享)互斥锁时死亡,它可以返回EOWNERDEAD。在这种情况下,尽管返回错误,调用者仍持有互斥锁,并可以通过调用 pthread_mutex_consistent 再次将受互斥保护的状态标记为有效。
      • 对于其所有者已死且新所有者调用 pthread_mutex_unlock 而未先调用 pthread_mutex_consistent 的健壮互斥体,它将返回 ENOTRECOVERABLE

      我可能错过了一些案例。请注意,这些都不适用于没有设置健壮属性的普通互斥锁(PTHREAD_MUTEX_NORMAL 类型),因此如果您只使用普通互斥锁,您可以合理地假设调用不会成功返回。

      【讨论】:

        【解决方案4】:

        来自POSIX standard

        如果互斥锁已经被锁定,调用线程将阻塞直到互斥锁可用。

        (...)

        如果在调用pthread_mutex_unlock() 时,mutex 引用的互斥对象上有线程阻塞,导致互斥锁可用,则调度策略应确定哪个线程应获取互斥锁。

        “resulting in”子句是必要的,因为

        (在PTHREAD_MUTEX_RECURSIVE互斥体的情况下,当计数达到零并且调用线程不再对该互斥体拥有任何锁时,互斥体将变为可用。)

        【讨论】:

          猜你喜欢
          • 2021-03-08
          • 2020-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-08
          • 1970-01-01
          • 2018-04-25
          • 1970-01-01
          相关资源
          最近更新 更多