C ++中pthread互斥锁的销毁和取消初始化顺序

scg

使用pthread互斥锁似乎很普遍,这种互斥锁要一直存在到程序生命周期的尽头。通常,这些是使用创建的PTHREAD_MUTEX_INITIALIZER

这是一个简短但完整的代码示例,显示了我所指的内容:

#include <pthread.h>

#include <iostream>

void log(char const * const message) {
    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

    pthread_mutex_lock(&mutex);
    std::cout << message << std::endl;
    pthread_mutex_unlock(&mutex);
}

struct Object final {
    Object() { log("Object::Object()"); }
    ~Object() { log("Object::~Object()"); }
};

Object const object;

int main(int const argc, const char * argv[]) {
    log("main()");

    // Here the program would enter a main loop, with log() potentially being
    // called from multiple threads at various times.
}

输出:

Object::Object()
main()
Object::~Object()

为简洁起见,省略了该锁的错误检查和RAII换行。

此示例包括线程安全(至少是意图)日志记录功能,该功能在程序的整个生命周期内都可用,包括在对具有静态存储持续时间的对象进行初始化期间,可能跨多个翻译单元(尽管不是这种情况) ,表示取消初始化的顺序可能不确定。

问题在于,没有机会安全地销毁互斥体,因为在程序生命周期的任何时候都可能需要它。(实际上,我不打算使用具有静态存储持续时间和非平凡析构函数的对象,但是我仍然有兴趣解决该问题。)

出现的第一个问题是,是否PTHREAD_MUTEX_INITIALIZER需要使用销毁使用初始化的互斥锁pthread_mutex_destroy()至少某些版本的文档包含以下措辞:

在适合使用默认互斥锁属性的情况下,可以使用宏PTHREAD_MUTEX_INITIALIZER初始化互斥锁。该效果应等同于通过将参数attr指定为NULL的pthread_mutex_init()调用来进行动态初始化,除了不执行任何错误检查。

这表明如果pthread_mutex_destroy()希望在使用初始化的互斥锁上调用pthread_mutex_init(),那么也希望在使用初始化的互斥锁上调用PTHREAD_MUTEX_INITIALIZER

但是,在联机搜索以及此处的Stack Overflow上,我发现是否需要它存在分歧。例如,在这里有人从一本有关Linux开发的书中提供以下报价:

不必在使用PTHREAD_MUTEX_INITIALIZER静态初始化的互斥锁上调用pthread_mutex_destroy()。

另一方面,在该线程中,有人指出,实际上需要明确销毁这种互斥体。

我也看到它认为,在这种情况下,不必初始化互斥量就不必清理互斥量,因为无论如何都会回收资源。(这可能与“首次使用并故意泄漏内存的构造”惯用法背后的逻辑相同,该惯用法有时用于单例和具有静态存储持续时间的其他对象。)

我发现了许多其他与主题相关的主题,对于是否应该/如何消除互斥锁也有很多意见。我还要提到的是,我相信我已经从可靠的来源中看到了生产代码,该代码使用互斥量进行初始化,PTHREAD_MUTEX_INITIALIZER并且从不销毁它们。

关于尽职调查,我在这里进行了详细介绍,但是我的问题很简单。具有从初始化到程序生命周期结束时可用的互斥体将很有用。我怀疑不清理此类互斥锁不会造成任何问题,但是这种方法困扰着我。即使有些人说PTHREAD_MUTEX_INITIALIZER不需要清除使用初始化的互斥锁,但这似乎与文档和其他人提出的各种主张背道而驰。

总而言之,是否存在一种安全合理的方法来管理打算在程序生命周期结束之前可用的pthread互斥锁?在这里,有没有我没有发现的标准最佳实践?

安东尼·威廉姆斯

由于初始化与PTHREAD_MUTEX_INITIALIZER等效于调用pthread_mutex_init,因此可以调用pthread_mutex_destroy销毁这种互斥锁。

但是,不需要致电pthread_mutex_destroy操作系统将在程序退出时回收资源。由于它是一个带有微不足道的析构函数的对象,因此它不会在程序退出时作为静态清理的一部分被销毁,因此可以安全使用,直到程序结束。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C对如何初始化和实现pthread互斥量和条件变量感到困惑

来自分类Dev

在C,C ++中初始化的顺序

来自分类Dev

C中互斥锁返回的顺序

来自分类Dev

了解C ++中的初始化顺序

来自分类Dev

如何在相互依赖的C文件中定义pthread和互斥锁?

来自分类Dev

在C / C ++中取消初始化变量

来自分类Dev

互斥锁与C ++ 11中的pthread兼容吗?

来自分类Dev

C ++-成员初始化和递增的顺序

来自分类Dev

如何在C ++中取消初始化对象?

来自分类Dev

大括号或相等初始化程序和初始化列表之间的C ++评估顺序?

来自分类Dev

模板中的C ++静态const初始化顺序

来自分类Dev

在C ++对象中初始化数据成员的正确顺序

来自分类Dev

再次关于C ++中的静态初始化顺序

来自分类Dev

C语言中for循环初始化中的评估顺序

来自分类Dev

在 C# 中,类的属性是并发初始化还是顺序初始化?

来自分类Dev

在C中使用互斥锁同步pthread

来自分类Dev

在C中使用互斥锁同步pthread

来自分类Dev

C ++使用互斥量字段初始化结构

来自分类Dev

C ++静态初始化顺序惨败

来自分类Dev

C ++静态初始化顺序惨败

来自分类Dev

C和C ++中的结构数组初始化

来自分类Dev

(共享)C ++中的互斥锁

来自分类Dev

C未初始化的互斥体有效并且初始化的互斥体失败了吗?

来自分类Dev

C和pthread:如何将互斥锁引用到特定变量?

来自分类Dev

初始化数组是否保留C / C ++和类似语言的顺序?

来自分类Dev

初始化数组是否保留C / C ++和类似语言的顺序?

来自分类Dev

C ++ 11中的数组声明和初始化

来自分类Dev

= {}和{}样式的初始化在C ++ 11中是否相同?

来自分类Dev

C ++ 11中的数组声明和初始化

Related 相关文章

热门标签

归档