如果C中的线程试图获取已有的锁,会发生什么?

时间:2017-11-12 07:17:46

标签: c multithreading pthreads locking mutex

假设有一个帖子, 线程通过以下方式获取锁定:

pthread_mutex_lock(&lock);

然后在解锁之前,它再次到达以下行:

pthread_mutex_lock(&lock);

pthread库是否会阻止线程的进展,还是会识别出线程已经持有锁,从而让它通过?

2 个答案:

答案 0 :(得分:7)

行为取决于互斥锁的类型。 POSIX standard表示递归锁定行为取决于锁的类型

  

如果某个线程尝试重新锁定它已锁定的互斥锁,pthread_mutex_lock()的行为应如下表的Relock列中所述。

使用Relock专栏说

  • PTHREAD_MUTEX_NORMAL类型的互斥锁将死锁
  • 类型PTHREAD_MUTEX_ERRORCHECK的互斥锁将返回错误
  • PTHREAD_MUTEX_RECURSIVE类型的互斥锁将作为递归锁定,然后您必须解锁锁定它的次数
  • 类型为PTHREAD_MUTEX_DEFAULT的互斥锁将具有未定义的行为,这实际上意味着如果在该平台上默认锁定是前3种类型中的任何一种,它将表现为特征在于上面的列,如果它是其他类型,那么行为将是未定义的。

因此,在测试 PTHREAD_MUTEX_DEFAULT锁中尤其没有必要找出行为是什么。

Linux manuals pthread_mutex_lock(3)改述了以下内容:

  

如果互斥锁已被调用线程锁定,          pthread_mutex_lock的行为取决于          那种互斥体。如果互斥锁是 fast          kind,调用线程被挂起,直到互斥锁          解锁,从而有效地导致呼叫          线程死锁。如果互斥锁是错误          检查种类,pthread_mutex_lock立即返回错误代码EDEADLK。如果互斥锁是          递归种类,pthread_mutex_lock成功并立即返回,记录数字          调用线程已锁定互斥锁的次数。一个          相同数量的pthread_mutex_unlock操作必须          在互斥锁返回解锁之前执行          状态。

在Linux中根据文档,默认类型是 fast ,但你不能依赖它是可移植的。

答案 1 :(得分:0)

POSIX支持多种不同的互斥锁类型。所有都使用相同的pthread_mutex_t类型,因此当重新锁定当前线程已获取的锁时,无法分辨pthread_mutex_lock的作用。

常见行为包括:

  • 常规互斥锁的自我死锁(pthread_mutex_lock永不返回)。
  • 错误检查互斥锁的错误(pthread_mutex_lock返回错误代码)。
  • 锁定操作成功,在锁定可用于其他线程锁定(递归互斥锁)之前,还需要再执行一次解锁操作。

使用属性pthread_mutex_init创建互斥锁时,可以选择互斥行为;见pthread_mutexattr_init。有些系统还提供非标准初始值设定项,如标准PTHREAD_MUTEX_INITIALIZER,它们可以创建不同的变体。