我读过Kerrisk的Linux编程接口:Linux和UNIX系统编程手册,第31章关于线程.本章包括线程特定数据(第31.3.4节)和线程本地存储(第31.4节).第663-669页介绍了这些主题.
线程特定数据(pthread_key_create,pthread_setspecific,pthread_getspecific,和朋友)看起来更加强大,但似乎多了几分使用麻烦,并显示使用内存管理器更频繁.
线程本地存储(__thread在静态和全局声明上)看起来不那么强大,因为它仅限于编译时间,但它似乎更容易使用,并且似乎在运行时不在内存管理器中.
关于运行时内存管理器我可能是错的,因为pthread_key_create在遇到__thread变量时可能会在幕后调用代码.
Kerrisk没有提供两种策略的比较/对比,他没有就何时使用哪种策略提出建议.
为问题添加上下文:我正在评估第三方库.库使用全局变量,也不能利用锁定了,我想在多线程程序中使用它.该程序使用线程来最小化网络延迟.
有没有赢家?或者有不同的情况需要使用其中一种吗?
根据pthread_key_create手册页,我们可以关联在线程关闭时调用的析构函数.我的问题是我注册的析构函数没有被调用.我的代码的要点如下.
static pthread_key_t key;
static pthread_once_t tls_init_flag = PTHREAD_ONCE_INIT;
void destructor(void *t) {
// thread local data structure clean up code here, which is not getting called
}
void create_key() {
pthread_key_create(&key, destructor);
}
// This will be called from every thread
void set_thread_specific() {
ts = new ts_stack; // Thread local data structure
pthread_once(&tls_init_flag, create_key);
pthread_setspecific(key, ts);
}
Run Code Online (Sandbox Code Playgroud)
知道什么可能会阻止这个析构函数被调用?我现在也在使用atexit()来在主线程中进行一些清理.有没有机会干扰被调用的析构函数?我也尝试删除它.虽然仍然没有奏效.另外我不清楚我是否应该将主线程作为atexit的单独案例来处理.(顺便说一下,使用atexit是必须的,因为我需要在应用程序出口处进行一些特定于应用程序的清理)
我正在使用 pthread 进行编程。我需要一个全局变量,它对于不同的线程具有不同的值。线程将使用相同的函数来处理该变量,例如更改其值。如果一个线程改变了它的值,其他线程中的值不会改变。所以我尝试使用线程特定数据,并编写了一个示例。我需要将 pthread 操作包装在函数中。例如:setspecific()、changedata、printdata()、create_key()、delete_key() 等。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_key_t key;
pthread_key_t key2;
struct test_struct {
int i;
float k;
}struct_data;
int temp;
int setspecificvar () { /* Set specific data for threads */
pthread_setspecific (key, &struct_data);
pthread_setspecific (key2, &temp);
return 0;
}
int changedata (int i, float k, int tempvar) { /* Change specific data for threads */
temp = tempvar;
struct_data.i = i;
struct_data.k = k;
return 0;
}
int printdata (int t) { /* …Run Code Online (Sandbox Code Playgroud) multithreading pthreads global-variables thread-specific-storage pthread-key-create