销毁锁定的互斥锁时 pthread_mutex_destroy 的正确行为是啥

Posted

技术标签:

【中文标题】销毁锁定的互斥锁时 pthread_mutex_destroy 的正确行为是啥【英文标题】:what is the correct behavior of pthread_mutex_destroy when destroying a locked mutex销毁锁定的互斥锁时 pthread_mutex_destroy 的正确行为是什么 【发布时间】:2014-04-16 19:36:09 【问题描述】:

我写了以下最小示例:

#include <iostream>
#include <cstring>
#include <pthread.h>
#define SUCCESS 0
using namespace std;

int main() 
    int res;
    pthread_mutex_t t;
    pthread_mutex_init(&t, NULL);

    res = pthread_mutex_lock(&t);

    res = pthread_mutex_destroy(&t);
    if (res != SUCCESS)
    
        cout << "Failed to delete: " << strerror(res) << " # " << t.__data.__lock << " " << t.__data.__nusers << endl;
    
    else
    
        cout << "Deleted!"<< endl;
    

    res = pthread_mutex_unlock(&t);
    cout << res << endl;
    pthread_exit(NULL);

    return 0;


也可以在ideone

正如有人指出的那样,the standard 显然是这样说的

尝试销毁锁定的互斥锁或被引用的互斥锁(例如,在 pthread_cond_timedwait() 或 pthread_cond_wait() 中被另一个线程使用时)会导致未定义的行为。

所以可以假设如果它同一个线程那么没关系。

这很奇怪,因为这句话在旧版本中被更改了它不存在并且该行只说

销毁已解锁的已初始化互斥体应该是安全的。尝试销毁锁定的互斥体会导致未定义的行为。

因此,认为此更改是有原因的并不是那么牵强,我只是想确定一下。

我在两个不同的 linux 系统(ubuntu 13.10 和另一个 debian 5774)上测试了前面提到的代码,它失败并打印“Failed to delete: Device or resource busy #1 1”,在 ideone 的平台上它成功了。

ideones 的行为是否只是未定义行为的特定情况?还是其他情况有问题?

很遗憾,我找不到专门解决此问题的来源。

【问题讨论】:

正如文中提到的,它是一个Undefined Behaviour @brokenfoot 是的,但它是否只是由另一个线程完成的情况?我试图澄清为什么有人会认为这很重要。 只要坚持 Posix 规范。是undefined behavior 【参考方案1】:

引用的文字:

尝试销毁锁定的互斥体或被另一个线程引用的互斥体(例如,在pthread_cond_timedwait()pthread_cond_wait() 中使用时)会导致未定义的行为

应该用分布在“或”连词上的“导致未定义行为”子句来解释。换句话说:

尝试销毁锁定的互斥体会导致未定义的行为

尝试销毁被另一个线程引用的互斥体(例如,在pthread_cond_timedwait()pthread_cond_wait() 中使用时)会导致未定义的行为

第二个版本很重要,因为在等待条件变量时,相关的互斥锁被等待线程释放。

【讨论】:

以上是关于销毁锁定的互斥锁时 pthread_mutex_destroy 的正确行为是啥的主要内容,如果未能解决你的问题,请参考以下文章

多个线程试图锁定

销毁全局对象[关闭]

如何正确销毁 pthread 互斥锁

TencentOS tiny深度源码分析—— 互斥锁

linux互斥锁简介(内核态)

std::mutex 如何在不同的线程中解锁?