【问题标题】:Does pthread_mutex_t in linux are reentrancy (if a thread tries to acquire a lock that it already holds, the request succeeds)linux中的pthread_mutex_t是否是可重入的(如果一个线程试图获取它已经持有的锁,则请求成功)
【发布时间】:2012-07-19 19:24:22
【问题描述】:

我来自 Java,所以我熟悉同步而不是互斥锁。 我想知道 pthread_mutex_t 是否也是可重入的。如果没有,还有其他机制吗?

谢谢

【问题讨论】:

标签: c++ c linux multithreading


【解决方案1】:

这取决于互斥体类型,默认情况下不进行检查,并且尝试在同一线程中多次锁定它会导致未定义的行为。阅读它here

您可以创建PTHREAD_MUTEX_RECURSIVE 类型的互斥体,以便能够递归锁定它,这是通过向pthread_mutex_init 提供具有所需互斥体类型的pthread_mutexattr_t 来完成的

【讨论】:

  • #include (c++11) 中的互斥量是否相同?
  • 还要注意递归和可重入不是一回事。递归互斥体不一定是可重入的,即从中断pthread_mutex_lock 的信号处理程序调用pthread_mutex_lock 会调用未定义的行为。然而,可以以可重入的方式实现pthread_mutex_lock;有关如何完成的示例,请参见我在 musl libc 中的实现。关键细节是单个原子操作必须将互斥体从未锁定状态转换为 lock-with-count-1 状态。
【解决方案2】:

根据the manual,可以将互斥对象声明为PTHREAD_MUTEX_RECURSIVE:

如果互斥锁类型是 PTHREAD_MUTEX_RECURSIVE,那么互斥锁应该 维护锁计数的概念。当一个线程成功 第一次获取互斥锁,锁计数设置为 一。每次线程重新锁定此互斥体时,锁定计数应为 加一。每次线程解锁互斥锁时,锁 计数应减一。当锁计数达到零时, 互斥锁应可供其他线程获取。如果一个 线程尝试解锁尚未锁定的互斥锁或互斥锁 解锁,返回错误。

另见pthread_mutex_attr_settype

【讨论】:

  • 谢谢。这是我一直在寻找的答案。
【解决方案3】:

默认情况下,pthread_mutex 不是递归的,但有一种方法可以将其初始化为递归:

      pthread_mutexattr_t Attr;
      pthread_mutexattr_init(&Attr);
      pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
      pthread_mutex_init(&_mutex, &Attr);

【讨论】:

  • 不是一个很有帮助的答案。添加对该代码的作用以及您要表达的观点的说明。
猜你喜欢
  • 1970-01-01
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多