【问题标题】:How do you handle pthread_mutex_unlock failures?你如何处理 pthread_mutex_unlock 失败?
【发布时间】:2011-09-14 20:04:23
【问题描述】:

假设一个线程成功调用pthread_mutex_lock,是否仍然有可能在同一个线程中调用pthread_mutex_unlock 会失败?如果是这样,除了中止线程之外,你真的可以做点什么吗?

if(pthread_mutex_lock(&m) == 0)
{
   // got the lock, let's do some work

   if(pthread_mutex_unlock(&m) != 0) // can this really fail?
   {
      // ok, we have a lock but can't unlock it?
   }
}

来自this pagepthread_mutex_unlock() 的可能错误是:

[EINVAL] 由 mutex 指定的值不引用初始化的 互斥对象。

如果锁定成功,那么这不太可能失败。

[再次] 无法获取互斥锁,因为最大数量 已超出互斥锁的递归锁。

真的吗?解锁?

如果出现以下情况,pthread_mutex_unlock() 函数可能会失败:

[EPERM] 当前线程不拥有互斥锁。

同样,如果锁定成功,那么这也不应该发生。

所以,我的想法是,如果锁定成功,那么在这种情况下,解锁应该永远不会失败,从而使错误检查和后续处理代码毫无意义。

【问题讨论】:

    标签: pthreads


    【解决方案1】:

    在你喊“胜利”之前。我最终在此页面上寻找我的一个程序在 pthread_mutex_unlock(在 HP-UX,而不是 Linux)上失败的原因。

    if (pthread_mutex_unlock(&mutex) != 0)
       throw YpException("unlock %s failed: %s", what.c_str(), strerror(errno));
    

    在数以百万计的快乐处决之后,这对我来说失败了。 errno 是EINTR,虽然我刚刚发现我不应该检查 errno,而是检查返回值。但是尽管如此,返回值不是 0。而且我可以从数学上证明,在那个地方我确实拥有一个有效的锁。

    所以我们只是说你的理论处于压力之下,尽管需要更多的研究;-)

    【讨论】:

    • 太棒了!或者也许不是很棒。 :-) 这正是我正在寻找的反馈。你能重现这个错误还是一次性的?知道实际返回值是多少会很有趣,因为 pthread_mutex_unlock() 不应该返回 EINTRerrno 或其他方式。
    • 我无法重现它。我修复了我的日志记录以显示实际的返回值,而不是 errno。下次它发生时(我希望不会)我会让你知道它到底是什么;-)
    • 小更新:我一直在发生错误的解锁失败,返回值 == 1,意思是“不是所有者”。事实证明这是一个非常微妙的错误。我将所有的锁都包裹在对象中(析构函数解锁)。这很方便,因为锁定与对象的范围一起自动结束。在这个函数中,我调用了 thread_exit()。手册页说您不能在 thread_exit() 之后使用自动变量。这正是我的锁包装对象的析构函数正在做的事情(隐式称为 AFTER thread_exit)。
    • 查看pthread_mutex_lock 的手册页,它说“如果成功,pthread_mutex_lock() 和 pthread_mutex_unlock() 函数应返回零;否则,应返回错误号以指示错误。 "我不认为你可以依靠它来设置errno
    【解决方案2】:

    来自 pthread_mutex_unlock 的手册页:

    The pthread_mutex_unlock() function may fail if:
    
    EPERM
    The current thread does not own the mutex.
    
    These functions shall not return an error code of [EINTR].
    

    如果您相信手册页,那么您的错误案例似乎不会发生。

    【讨论】:

    • 谢谢,这也是我的想法。我更新了这个问题,希望能更清楚地说明我为什么要问。在我接受答案之前,我想先看看能否得到任何其他意见。
    猜你喜欢
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多