pthread:销毁全局静态互斥量 [英] pthread: destroying global static mutex
问题描述
此代码摘自Richard Stevens编写的UNIX环境中的第三版高级编程.这是如何制作getenv()
的可重入版本的示例.这里仅出于学习目的对其进行演示.
This code was taken from the 3rd edition of Advanced Programming in the UNIX Environment, written by Richard Stevens. This is an example of how to make a reentrant version of getenv()
. It is demostrated here only for a learning purpose.
/* Copyright (c) W.R.Stevens */
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
extern char **environ;
pthread_mutex_t env_mutex;
static pthread_once_t init_done = PTHREAD_ONCE_INIT;
static void
thread_init(void)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&env_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
int
getenv_r(const char *name, char *buf, int buflen)
{
int i, len, olen;
pthread_once(&init_done, thread_init);
len = strlen(name);
pthread_mutex_lock(&env_mutex);
for (i = 0; environ[i] != NULL; i++) {
if ((strncmp(name, environ[i], len) == 0) &&
(environ[i][len] == '=')) {
olen = strlen(&environ[i][len+1]);
if (olen >= buflen) {
pthread_mutex_unlock(&env_mutex);
return(ENOSPC);
}
strcpy(buf, &environ[i][len+1]);
pthread_mutex_unlock(&env_mutex);
return(0);
}
}
pthread_mutex_unlock(&env_mutex);
return(ENOENT);
}
此代码易于理解.但我有个问题.我们从不调用pthread_mutex_destroy()
,这意味着退出时可能会发生内存泄漏(我猜这在平台之间可能会有所不同).
This code is easy to understand. I have a question though. We're never calling pthread_mutex_destroy()
, which means that there may be a memory leak on exit (I guess it may differ between platforms).
首先想到的是一个人可以使用PTHREAD_MUTEX_INITIALIZER
.是否需要pthread_mutex_init()
调用?如果否,则无需调用pthread_mutex_destroy()
.但是,互斥锁将是非递归的.
First thing that comes to mind is that one may use PTHREAD_MUTEX_INITIALIZER
. Does it require pthread_mutex_init()
call? If no, there is no need to call pthread_mutex_destroy()
. However, the mutex will be non-recursive.
可以编写一个简单的C ++类,该类可以销毁析构函数中的互斥量.但是,它不适合仅使用C编译器的任何人(由于使用一个函数,使用C ++编译器似乎是胡说八道).
One could write a simple C++ class that could destroy mutex in destructor. However, it is not suitable for anyone who has only C compiler (and it seems to be a bullshit to use C++ compiler because of one function).
想到的另一件事是特定于编译器的扩展,例如GCC中的__attribute__((destructor))
(可能还有clang).但是,它是不可携带的.
The other thing that comes to mind are compiler-specific extensions like __attribute__((destructor))
in GCC (and hopefully clang). However, it is non-portable.
是否可以避免内存泄漏?如果是的话,那该如何在C语言中完成?
Is it possible to avoid a memory leak? If yes, how can that be done in C?
更新
正如David Butenhof撰写的使用POSIX线程编程"中所出现的那样,我们无需销毁PTHREAD_MUTEX_INITIALIZER
变体.具有其他属性的互斥锁如何?
UPDATE
As appears in "Programming with POSIX threads" written by David Butenhof, we never need to destroy PTHREAD_MUTEX_INITIALIZER
variant. How about mutexes with other attributes?
推荐答案
在进程终止时仍处于活动状态的资源不是内存泄漏,尽管有一些幼稚的工具将其归类.内存泄漏是程序在生命周期中资源需求的不可逆转且无止境的增长,与实际工作集不成比例.
Resources that are still live at process termination are not memory leaks, despite some naive tools classifying them as such. A memory leak is an irreversible and unbounded growth of a program's resource requirements during its lifetime that's disproportionate to the actual working set.
对于每个POSIX(可在其中获得POSIX线程),在程序终止时,所有本地进程资源将不复存在.无需明确销毁/释放它们,在某些情况下,像您一样,您不能安全地销毁/释放它们,并且不应尝试.
Per POSIX (which is where you get POSIX threads), all process-local resources cease to exist at program termination. There is no need to destroy/free them explicitly, and in some cases, like yours, you cannot safely destroy/free them and you should not try to.
这篇关于pthread:销毁全局静态互斥量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!