C语言 静态初始值设定项宏是否需要动态清理?(pthread_mutex_initializer需要pthread_mu



我已经查看了有关此主题的许多其他问题,并且我觉得我了解了该主题...但我想讨论这个问题的一个方面。

如此处所述 销毁静态互斥锁和 rwlock 初始值设定项

(没有必要在使用PTHREAD_MUTEX_INITIALIZER静态初始化的互斥锁上调用 pthread_mutex_destroy((。

然而,我想提出一个更基本的问题:

如果 API 提供了一个宏来初始化对象/类型,类似于PTHREAD_MUTEX_INITIALIZER,那么宏是否可以扩展到需要调用动态析构函数的任何内容?

澄清我在问什么:

PTHREAD_MUTEX_INITIALIZER中是否可以执行任何需要动态析构函数来清理的操作?

是否可以安全地假设,如果对象/类型具有像PTHREAD_MUTEX_INITIALIZER这样的静态宏初始值设定项,则宏不可能初始化任何需要动态清理的内容,因此pthread_mutex_destroy不可能是PTHREAD_MUTEX_INITIALIZER所必需的?

或者将来是否有可能更改某些内容,这可能会导致PTHREAD_MUTEX_INITIALIZER执行一些绝对需要调用pthread_mutex_destroy函数的操作?

编辑:我唯一能想到的就是注册一个 gcc__attribute__((constructor))或其他东西,以便自动调用一些代码,此时它不再是真正的静态初始化,对吧?如果它确实是静态初始化,那么根据定义,这意味着它不能做任何动态的事情;因此,根据定义,静态初始值设定项宏不需要动态清理函数,对吧?

如果 API 提供了一个宏来初始化对象/类型,类似于PTHREAD_MUTEX_INITIALIZER,那么宏有什么可以做的吗 向外扩展需要调用动态析构函数 功能?

一般来说,是的。 宏可以扩展到函数调用或包含函数的初始值设定项,这可能会返回指向动态分配空间的指针或包含此类指针的结构或联合。

但是对于PTHREAD_MUTEX_INITIALIZER或任何其他可用于初始化文件范围变量的宏,否。 此类初始值设定项必须由常量表达式构造,并且此类初始值设定项不能包含任何强制清理的内容。

但是,请注意,这不是一个完整的故事。 无论对象如何初始化,其后续使用都可能导致需要通过析构函数释放资源以遵循它。 特别是,POSIX不承诺未能销毁通过宏初始化的互斥锁不会产生任何后果。 它也没有区分通过初始值设定项宏初始化的互斥锁的初始状态和通过具有默认属性pthread_mutex_init()初始化的互斥锁的初始状态。 无论哪种方式,需要清理的资源都可以通过调用pthread_mutex_lock()与此类互斥锁相关联,例如。

但不要忽视,在这个领域里,任何"要求"都是有条件的,而不是绝对的。 可能需要调用pthread_mutex_destroy()才能实现所需的结果,例如避免资源泄漏。 不打电话意味着获得不同的结果,这可能仍然是一个可以接受的结果。

也许一个很好的例子是NULL宏。 任何指针对象都可以用NULL初始化,这没有任何资源管理影响。 但是,如果随后为其分配了指向动态分配空间的指针,则未能将该对象的值传递给free()可能会导致资源泄漏。 然而,这样的泄漏可能是可以接受的 - 例如,如果分配的空间无论如何都需要保留到程序终止,那么程序是否自行释放它,或者它是否依赖于操作系统来处理它作为清理过程的一部分,几乎没有实际区别。

这句话是Linux特有的,并且是在Linux上,pthread_mutex_destroy本质上是一个noop的结果。 从手册页:

pthread_mutex_destroy销毁互斥对象,释放它可能拥有的资源。这 互斥锁必须在入口处解锁。在 LinuxThreads 实现中,没有资源 与互斥对象相关联,因此pthread_mutex_destroy实际上什么都不做,除了 检查互斥锁是否已解锁。

因此,在 Linux 上,对于任何互斥锁,都不需要pthread_mutex_destroy。

最新更新