pthread_key_create 会导致内存泄漏吗?
Does pthread_key_create cause memory leak?
我有一个程序,它有一个 static pthread_key_t key
变量和一个在第一个线程启动时调用 pthread_key_create(&key, &cleanup_function)
的函数。我不想在清理例程中调用 pthread_key_delete
,因为它会在线程退出时调用 运行,而不是在所有线程退出时调用。如果另一个线程稍后调用 get_specific
或 set_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);
...
}
程序看起来像这样。
I have a program that has a static pthread_key_t key
variable and a function that calls pthread_key_create(&key, &cleanup_function)
when the first thread is started.
我猜你是指 第二个 线程,或者第一个通过 pthread_create()
启动的线程 每个进程在启动时都有一个线程。所有执行的代码都在一个线程中执行。
此外,“何时”有点繁琐。最干净的是初始线程创建密钥,在 启动任何其他线程之前。否则,您需要进行额外的同步以避免数据竞争。
I don't want to call pthread_key_delete
in the cleanup routine because it will run whenever a thread exits instead of when all threads have exited.
文档将您的“清理函数”称为析构函数,我发现该术语更能说明预期目的:不是通用清理,而是线程的适当拆卸-与键关联的特定值。然而,您仍然得出了正确的结论。析构函数(如果给定的话)应该只销毁一个值,而不是键。
Can I just completely leave out pthread_key_delete
? Will this (having called pthread_key_create
without calling pthread_key_delete
afterward) cause any memory leak when the program eventually comes to a halt?
那是未指定的,所以确保调用pthread_key_delete()
是最安全的。如果使用密钥的所有线程都是可连接的,那么您可以在加入它们后执行此操作。您也可以考虑注册一个 exit handler 来做到这一点,但显式销毁密钥是更好的方式,可以合理地执行。
话虽如此,如果销毁密钥失败,您不会泄漏任何普通内存,因为当进程退出时,系统会回收属于该进程的所有资源。主要风险是与密钥关联的某些资源的范围会更广,并且它们会泄漏。命名信号量和内存映射文件是此类资源的示例,但我不知道与 TLD 密钥关联的那些特定类型的资源。
does the key just go into the garbage collector or get destructed once the entire problem ends?
C 实现通常不实现垃圾收集,尽管有用于 C 的附加垃圾收集器框架。但是如上所述,属于进程的资源确实会在进程终止时由系统释放。
我有一个程序,它有一个 static pthread_key_t key
变量和一个在第一个线程启动时调用 pthread_key_create(&key, &cleanup_function)
的函数。我不想在清理例程中调用 pthread_key_delete
,因为它会在线程退出时调用 运行,而不是在所有线程退出时调用。如果另一个线程稍后调用 get_specific
或 set_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);
...
}
程序看起来像这样。
I have a program that has a
static pthread_key_t key
variable and a function that callspthread_key_create(&key, &cleanup_function)
when the first thread is started.
我猜你是指 第二个 线程,或者第一个通过 pthread_create()
启动的线程 每个进程在启动时都有一个线程。所有执行的代码都在一个线程中执行。
此外,“何时”有点繁琐。最干净的是初始线程创建密钥,在 启动任何其他线程之前。否则,您需要进行额外的同步以避免数据竞争。
I don't want to call
pthread_key_delete
in the cleanup routine because it will run whenever a thread exits instead of when all threads have exited.
文档将您的“清理函数”称为析构函数,我发现该术语更能说明预期目的:不是通用清理,而是线程的适当拆卸-与键关联的特定值。然而,您仍然得出了正确的结论。析构函数(如果给定的话)应该只销毁一个值,而不是键。
Can I just completely leave out
pthread_key_delete
? Will this (having calledpthread_key_create
without callingpthread_key_delete
afterward) cause any memory leak when the program eventually comes to a halt?
那是未指定的,所以确保调用pthread_key_delete()
是最安全的。如果使用密钥的所有线程都是可连接的,那么您可以在加入它们后执行此操作。您也可以考虑注册一个 exit handler 来做到这一点,但显式销毁密钥是更好的方式,可以合理地执行。
话虽如此,如果销毁密钥失败,您不会泄漏任何普通内存,因为当进程退出时,系统会回收属于该进程的所有资源。主要风险是与密钥关联的某些资源的范围会更广,并且它们会泄漏。命名信号量和内存映射文件是此类资源的示例,但我不知道与 TLD 密钥关联的那些特定类型的资源。
does the key just go into the garbage collector or get destructed once the entire problem ends?
C 实现通常不实现垃圾收集,尽管有用于 C 的附加垃圾收集器框架。但是如上所述,属于进程的资源确实会在进程终止时由系统释放。