在C语言中,pthread_mutex_t是否需要在使用后释放?

k4ymrczo  于 2023-02-11  发布在  其他
关注(0)|答案(2)|浏览(239)

我在程序中使用pthread_mutex_t进行线程同步控制。
pthread_mutex_t不再使用时,我是否需要做一些收尾工作?
或者,我什么也不能做?
谢谢你的帮忙

ppcbkaq5

ppcbkaq51#

您提到 “pthread_mutex_t不再使用”
我想你的意思是你不再需要使用它,永远,在你的任何线程。

在这种情况下:

  1. pthread_mutex_t必须处于解锁状态
    1.你应该打电话给pthread_mutex_destroy
    pthread_mutex_destroy的文档中列出了对互斥锁进行解锁的要求:
    销毁一个未锁定的初始化互斥锁应该是安全的。试图销毁一个锁定的互斥锁会导致未定义的行为
  • (重点是我)*

这篇文章包含了一些关于正确使用pthread_mutex_destroy的更多信息:
How to safely and correctly destroy a mutex in Linux using pthread_mutex_destroy? .

icnyk63a

icnyk63a2#

我在程序中使用pthread_mutex_t进行线程同步控制。
pthread_mutex_t不再使用时,我是否需要做一些收尾工作?
或者,我什么也不能做?

    • TL; DR**:你不需要做任何清理。在某些情况下你应该做,而在其他情况下这是一个风格的问题。在某些情况下,这个问题是没有实际意义的,因为不可能识别出互斥锁不再使用。

此处"不再使用"的相关含义是互斥锁当前未被任何线程锁定(包括可能执行清理的线程),并且不可能有任何线程在将来试图锁定它。对于这种情况,pthread_mutex_destroy()函数可用于释放互斥体可能持有的任何资源(不包括互斥对象本身所占用的存储空间)。在其他任何情况下,销毁互斥对象都会使程序面临执行未定义行为的风险。
如果一个给定的互斥体对象曾经被初始化过,包括通过静态初始化器初始化,并且它的生命周期结束于自上次初始化以来还没有被销毁的点,那么它的生命周期的结束必须被假定为泄漏资源。但是,只有当互斥体的生命周期在程序结束之前结束时,这才是重要的。因为当一个进程终止时,属于该进程的所有资源都被操作系统清除。2特别是,在任何翻译单元的文件作用域中声明互斥对象的常见情况下,这并不是必然的。
指导,然后:
1.作为正确性问题,您 * 必须 * 确保
1.互斥对象的生存期在其仍在使用时不会结束。
1.在互斥锁仍在使用中或在其生命周期结束后,不会销毁互斥锁。
1.实际上,你应该避免间接的资源泄漏,因为它们可能最终导致程序失败和/或资源耗尽给整个系统带来压力。在这种情况下,这意味着使用pthread_mutex_destroy()在互斥对象的生命周期结束之前清理那些具有自动、已分配或线程存储持续时间的互斥对象,如果这在整个程序结束之前发生。
1.作为一个风格问题,您 * 可能 * 选择将类似的规则应用于具有静态存储持续时间的互斥对象--可能只应用于那些通过pthread_mutex_init()初始化的互斥对象,或者也可能包括那些通过静态初始化器宏初始化的互斥对象。我本人倾向于不担心这些互斥对象,因为很少有很多互斥对象,而且在程序即将终止之前,它们也很少停止使用。
1.作为一个风格问题,你 * 不应该 * 做出英勇的努力或者过度复杂化你的代码来确保互斥锁在程序终止时被显式地销毁。无论如何,操作系统会执行所有必要的清理,而任何需要大量努力才能在第一时间正确编写的清理(或其他)代码都是错误的沃土,并且具有很高的维护成本。
最后,请注意,有些情况下,您甚至无法在程序终止之前识别出给定的互斥体不再使用。例如,考虑一个程序,它声明了一个文件范围的互斥体,用于同步几个守护进程线程的操作。很可能系统中没有线程可以确定是否所有的互斥体都已停止使用。(其他)守护进程线程已经终止,以便知道互斥体不再使用,因此没有安全的方法,只能避免显式地破坏它。

相关问题