此代码摘自 Richard Stevens 编写的第 3 版 UNIX 环境中的高级编程。这是一个如何制作 getenv()
的可重入版本的示例。此处演示仅供学习。
/* 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()
,这意味着退出时可能会发生内存泄漏(我猜这可能因平台而异)。
首先想到的是可以使用 PTHREAD_MUTEX_INITIALIZER
。是否需要 pthread_mutex_init()
调用?如果不是,则无需调用 pthread_mutex_destroy()
。但是,互斥量将是非递归的。
可以编写一个简单的 C++ 类,在析构函数中销毁互斥量。但是,它并不适合任何只有C编译器的人(而且因为一个功能而使用C++编译器似乎是在扯淡)。
想到的另一件事是特定于编译器的扩展,例如 GCC 中的 __attribute__((destructor))
(希望是 clang)。但是,它是不可携带的。
是否有可能避免内存泄漏?如果是,如何在 C 中完成?
更新
正如 David Butenhof 所写的“Programming with POSIX threads”中所述,我们永远不需要销毁 PTHREAD_MUTEX_INITIALIZER
变体。具有其他属性的互斥锁怎么样?
最佳答案
在进程终止时仍然存在的资源不是内存泄漏,尽管一些简单的工具将它们归类为内存泄漏。内存泄漏是程序在其生命周期内对资源需求的不可逆转和无限增长,这与实际工作集不成比例。
根据 POSIX(这是您获得 POSIX 线程的地方),所有进程本地资源在程序终止时不再存在。没有必要明确地销毁/释放它们,在某些情况下,例如您的情况,您不能安全地销毁/释放它们并且您不应该尝试。
关于c - pthread : destroying global static mutex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26899569/