7

C 编程:

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

它会睡觉吗?

pthread_mutex_unlock(&mutex); 时是否会唤醒线程?叫做?

然后再次尝试获取锁?

4

4 回答 4

9

手册页

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

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

于 2011-03-11T01:00:24.110 回答
4

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

如果其他人拥有锁,或者如果它获得了锁,非阻塞版本pthread_mutex_trylock(pthread_mutex_t *mutex)将会返回。(或者其他一些错误,当然)EBUSY0

于 2011-03-11T01:05:01.657 回答
3

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

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

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

于 2011-03-11T01:21:21.007 回答
0

POSIX 标准

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

(...)

mutex如果调用when引用的互斥对象上有线程阻塞,导致互斥对象pthread_mutex_unlock()可用,调度策略将决定哪个线程获取互斥对象。

“导致”条款是必要的,因为

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

于 2011-03-11T01:10:35.210 回答