使用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] 删除。
我来说两句