c-pthread_key_create是否会导致内存泄漏



我有一个程序,它有一个static pthread_key_t key变量和一个在第一个线程启动时调用pthread_key_create(&key, &cleanup_function)的函数。我不想在清理例程中调用pthread_key_delete,因为它将在线程退出时运行,而不是在所有线程都退出时运行。如果稍后另一个线程调用get_specificset_specific,这将导致问题。我的问题是:我可以完全忽略pthread_key_delete吗?当程序最终停止时,这(调用pthread_key_create而不调用pthread_key_delete(会导致内存泄漏吗?创建pthread_key_t后是否必须调用pthread_key_delete?或者密钥只是进入垃圾收集器,或者在整个问题结束后被销毁?

static pthread_key_t key = NULL;
...
static void cleanup(void *value) {
...
if (thread_exit_callback) {
thread_exit_callback(value);
}
free(value);
}
static void *start(void *value) {
...
if (key == NULL){
pthread_key_create(&key, &cleanup);
}
pthread_setspecific(key, value);
...
}

程序看起来像这样。

我有一个程序,它有一个static pthread_key_t key变量和一个函数,该函数在第一个线程启动时调用pthread_key_create(&key, &cleanup_function)

我想你指的是第二个线程,或者第一个通过pthread_create()启动的线程。每个进程在启动时都有一个线程。所有执行的代码都在线程中执行。

此外;当";有点麻烦。初始线程创建密钥是最干净的,并且在启动任何其他线程之前。否则,您需要进行额外的同步以避免数据竞争。

我不想在清理例程中调用pthread_key_delete,因为它将在线程退出时运行,而不是在所有线程都退出时运行。

文档引用您的";清除功能";作为析构函数,我发现这个术语更能说明预期目的:不是通用的清理,而是与键相关的线程特定值的适当拆卸。然而,你还是得出了正确的结论。如果给定了析构函数,则应该只拆下一个值,而不是键。

我可以完全忽略pthread_key_delete吗?当程序最终停止时,这(调用pthread_key_create而不调用pthread_key_delete(会导致内存泄漏吗?

这是未指定的,因此确保调用pthread_key_delete()是最安全的。如果所有使用键的线程都是可连接的,那么您可以在连接它们之后再进行连接。您也可以考虑注册一个退出处理程序来完成此操作,但显式销毁密钥是可以合理执行的更好方式。

话虽如此,如果未能销毁密钥,则不会泄漏任何普通内存,因为当进程退出时,系统将回收属于该进程的所有资源。主要风险是,与密钥相关的一些资源的范围会更广,并且会泄漏。命名信号量和内存映射文件就是这样的资源的例子,尽管我不知道那些与TLD密钥相关联的特定类型的资源。

密钥是直接进入垃圾收集器,还是在整个问题结束后被销毁?

C实现通常不实现垃圾回收,尽管有针对C的插件垃圾回收器框架。但如上所述,当进程终止时,属于进程的资源确实会被系统释放。

最新更新