英文:
In C language, do pthread_mutex_t need to be released after use?
问题
我在我的程序中使用pthread_mutex_t
进行线程同步控制。
当pthread_mutex_t
不再使用时,我需要做一些清理工作吗?
或者,我什么都不需要做吗?
谢谢你的帮助。
英文:
I use pthread_mutex_t
in my program for thread synchronization control.
Do I need to do some finishing works when the pthread_mutex_t
is no longer in use?
Or, can I do nothing?
Thank you for your help
答案1
得分: 5
你提到_"pthread_mutex_t不再使用"_。
我理解你的意思是你在任何线程中都不再需要使用它。
在这种情况下:
pthread_mutex_t
必须处于解锁状态。- 你应该调用
pthread_mutex_destroy
。
关于互斥锁必须处于解锁状态的要求在 pthread_mutex_destroy
的文档中有说明:
> 可以安全地销毁一个处于初始化并且解锁状态的互斥锁。
> 尝试销毁一个被锁住的互斥锁会导致未定义的行为。
(强调是我的)
这篇帖子包含了关于 pthread_mutex_destroy
正确使用的更多信息:
https://stackoverflow.com/questions/46345261/how-to-safely-and-correctly-destroy-a-mutex-in-linux-using-pthread-mutex-destroy。
英文:
You mention that "the pthread_mutex_t is no longer in use".
I assume you mean that you no longer need to use it, ever, in any of your threads.
In this case:
- The
pthread_mutex_t
must be in the unlocked state. - You should call
pthread_mutex_destroy
.
The requirement for the mutex to be unlocked appears in the documentation for pthread_mutex_destroy
:
> It shall be safe to destroy an initialized mutex that is unlocked.
> Attempting to destroy a locked mutex results in undefined behavior.
(emphasis is mine)
This post contains some more info about the proper usage of pthread_mutex_destroy
:
https://stackoverflow.com/questions/46345261/how-to-safely-and-correctly-destroy-a-mutex-in-linux-using-pthread-mutex-destroy.
答案2
得分: 2
我在程序中使用pthread_mutex_t
来进行线程同步控制。当pthread_mutex_t
不再使用时,不需要进行任何清理工作。在某些情况下,可能需要进行清理,而在其他情况下可能只是一种风格问题。在某些情况下,问题可能根本无法确定互斥锁不再使用。
在这里,“不再使用”的相关意义是互斥锁当前没有被任何线程锁定(包括执行清理的线程),并且没有可能会有任何线程在将来尝试锁定它。对于这种情况,可以使用pthread_mutex_destroy()
函数来释放互斥锁可能持有的任何资源(不包括互斥锁对象本身占用的存储空间)。在任何其他情况下,销毁互斥锁会使程序面临未定义行为的风险。
如果某个互斥锁对象曾经被初始化过,包括通过静态初始化器,且其生命周期在自上次初始化后未被销毁的情况下结束,那么必须假定其生命周期结束会导致资源泄漏。但这只在互斥锁的生命周期在程序结束之前结束时才会产生后果,因为进程中属于所有资源都会在进程终止时被清理。特别地,这在任何翻译单元中以文件范围声明的互斥锁对象的常见情况下不会产生后果。
因此,以下是一些指导:
- 从正确性的角度来看,必须确保互斥锁对象的生命周期不会在它仍在使用时结束。
- 从实际角度来看,应避免产生后果严重的资源泄漏,因为它们最终可能导致程序失败和/或资源耗尽引发系统压力。在这种情况下,这意味着在互斥锁对象的生命周期明显在整个程序结束之前结束时,使用
pthread_mutex_destroy()
来清理具有自动、分配或线程存储期的互斥锁对象。 - 从风格角度来看,可以选择将类似的纪律应用于具有静态存储期的互斥锁对象--也许仅限于通过
pthread_mutex_init()
初始化的那些,或者还包括通过静态初始化宏初始化的那些。我个人不太担心这些情况,因为它们很少很多,而且它们在程序终止之前很少被不再使用。 - 从风格角度来看,不应为确保在程序终止时显式销毁互斥锁而进行艰苦的努力或过于复杂化代码。操作系统将执行所有必要的清理,而任何(或其他)代码,写起来在第一次正确编写时需要付出大量努力的代码,都是错误的肥沃土壤,成本高昂。
最后,请注意,有些情况下,甚至在程序终止之前,你无法确定某个互斥锁不再使用。例如,考虑一个声明了文件范围互斥锁用于同步多个守护线程操作的程序。很可能没有一个线程可以确定所有(其他)守护线程是否已终止,以便知道互斥锁不再使用,因此唯一安全的方式是避免显式销毁它。
英文:
> I use pthread_mutex_t
in my program for thread synchronization
> control.<br/> Do I need to do some finishing works when the
> pthread_mutex_t
is no longer in use?<br/> Or, can I do nothing?
TL;DR: You do not need to do any cleanup. In some cases you should, and in other cases it's a question of style. And in some cases, the question is moot because it's not possible to recognize that a mutex is no longer in use.
The relevant sense of "no longer in use" here would be that the mutex is not currently locked by any thread (including the one that might perform cleanup), and there is no possibility that any thread will attempt to lock it in the future. For this case, the pthread_mutex_destroy()
function is available to release any resources that the mutex may be holding (not including the storage occupied by the mutex object itself). In any other case, destroying the mutex puts your program at risk of exercising undefined behavior.
If a given mutex object has ever been initialized, including via the static initializer, and its lifetime ends at a point when it has not been destroyed since its last initialization, then the end of its lifetime must be assumed to leak resources. But this is consequential only when the mutex's lifetime ends before the end of the program, because all resources belonging to a process are cleaned up by the OS when the process terminates. In particular, it is not consequential in the common case of mutex objects declared at file scope in any translation unit.
Guidance, then:
-
As a correctness matter, you must ensure that
- The lifetime of a mutex object does not end while it is still in use.
- No mutex is destroyed while it is still in use or after the end of its lifetime.
-
As a practical matter, you should avoid consequential resource leaks, as they may ultimately lead to program failure and / or overall system stress from resource exhaustion. In this context, that means using
pthread_mutex_destroy()
to clean up mutex objects having automatic, allocated, or thread storage duration before those objects' lifetimes end, when that occurs significantly before the end of the program overall. -
As a style matter, you might choose to apply a similar discipline to mutex objects having static storage duration -- perhaps only those initialized via
pthread_mutex_init()
, or perhaps including also those initialized via the static initializer macro. I tend not to worry about these, myself, as there are rarely very many, and they rarely go out of use very much before the program is going to terminate anyway. -
As a style matter, you should not make heroic efforts or overly complicate your code to ensure that mutexes are explicitly destroyed when the program is terminating. The OS is going to perform all necessary cleanup anyway, and any cleanup (or other) code that takes a lot of effort to write correctly in the first place is fertile ground for bugs and has high maintenance cost.
Finally, note well that there are cases when you can't even recognize before program termination that a given mutex is no longer in use. For example, consider a program that declares a file-scope mutex used to synchronize the operations of several daemon threads. It may well be that no thread in the system can determine whether all the (other) daemon threads have terminated, so as to know that the mutex is no longer in use, so there is no safe course but to avoid ever destroying it explicitly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论