【问题标题】:Possible to check mutex is locked before calling pthread_cond_wait()?可以在调用 pthread_cond_wait() 之前检查互斥锁是否已锁定?
【发布时间】:2012-03-01 07:41:16
【问题描述】:

我想在我的代码中将一些调试代码添加到pthread_cond_wait 的抽象中,以检查调用代码是否真的持有互斥锁,因为它应该。这是为了检查其余调用者的正确性。

有没有办法检查互斥锁是否被锁定,或者在 pthreads 实现中启用调试模式(在 Linux 上)告诉我是否没有?

【问题讨论】:

  • 如果此时您拥有互斥锁还不是很明显,那么您的代码需要认真修复...
  • @R.. 对于简单的情况,没问题。随着代码的增长和变得更加复杂,并且随着时间的推移由不同的人处理,变得不那么明显了。验证优于依赖“明显”的正确性。
  • 如果持有锁的范围定义太差以至于当你到达pthread_cond_wait时你不确定它是否被持有,那么代码几乎肯定充满了死锁。在好的代码中,在您可能调用同步原语的任何特定点,您持有的相关锁集应该是静态约束(相对于反映您正在处理的对象的可变参数)。

标签: c linux pthreads


【解决方案1】:

如果您将互斥锁创建为错误检查互斥锁,请使用:

pthread_mutexattr_t attr;
pthread_mutex_t errchkmutex;

pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&errchkmutex, &attr);

...如果互斥体未被调用线程锁定,pthread_cond_wait() 将返回 EPERM

(当然,您会在该互斥体初始化代码中添加错误检查)。

我认为错误检查互斥锁正是您正在寻找的那种“调试模式”。

【讨论】:

    【解决方案2】:

    pthread_cond_wait 将失败,除非互斥锁被调用线程锁定。您是否正在检查 pthread 函数的返回值?如果不是这样,这就是灾难的根源,线程比其他系统调用更是如此。

    【讨论】:

    • 我的手册页显示“pthread_cond_init、pthread_cond_signal、pthread_cond_broadcast 和 pthread_cond_wait 永远不会返回错误代码。”
    • 您的联机帮助页有误(linux 文档一直都是废话),或者您正在运行一些不支持 POSIX 语义的模糊版本的 linux。如果“调用时当前线程不拥有互斥锁”,则指定 pthread_cond_wait 返回 EPERM。例如,请参见:compute.cnr.berkeley.edu/cgi-bin/man-cgi?pthread_cond_wait+3(无论如何,您都可以编写一个简单的测试程序。)
    • 我测试过。 pthread_cond_wait() 工作正常,如果互斥锁没有被调用线程锁定,则在我的开发 Linux 机器和嵌入式 Linux 目标上都返回 0。
    • 那么你应该向 libc 和内核维护者报告一个错误。
    • EPERM 仅与错误检查互斥锁相关(可能还有递归互斥锁,但 opengroup.org 目前已关闭,而且我手边没有 POSIX 的本地副本)。对于普通的互斥体,在不持有互斥体的情况下调用pthread_cond_wait 是UB。因此,如果您提到需要使互斥锁成为错误检查之一,那么这个答案将完全解决 OP 的问题!
    【解决方案3】:

    从 zvrba 和 "R" 以及其他一些研究中拼凑出的答案是创建具有错误检查属性的互斥锁并检查 pthread_cond_wait() 的返回值。

    pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ERRORCHECK);
    

    其他相关信息:

    • 我的 glibc 在任何包含之前都需要 #define _GNU_SOURCE 才能启用 pthread_mutexattr_settype()

    • 我发现我确实安装了 POSIX 手册页以及“LinuxThreads”手册页。我不确定各种包来自什么 (ubuntu) 包,但编辑 /etc/manpath.config 以首先放置“3posix”意味着我现在得到了正确的包。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 2011-05-20
      相关资源
      最近更新 更多