-
Gcc and clang's __thread Modifier -
Msvc's __declspec(thread) Modifier -
Pthread library pthread_setspecific and pthread_getspecific Interface -
Windows TlsSetValue and TlsGetValue
__Use of thread and __declspec (thread)
tb_void_t tb_thread_func(tb_cpointer_t priv) { //Define a thread local variable static __thread int a = 0; //Initialize this variable and set it to the current thread id if (! a) a = tb_thread_self(); }
Pthread interface
//The key stored in the tls variable in the test thread needs to be defined as global or static static pthread_key_t g_local_key = 0; static tb_void_t tb_thread_local_free(tb_pointer_t priv) { tb_trace_i("thread[%lx]: free: %p", tb_thread_self(), priv); } static tb_void_t tb_thread_local_init(tb_void_t) { //Create the key of the tls and set the automatic release function pthread_key_create(&g_local_key, tb_thread_local_free); } static tb_int_t tb_thread_local_test(tb_cpointer_t priv) { //In all threads, it is executed only once, which is used to initialize the key of tls inside the thread static pthread_once_t s_once = PTHREAD_ONCE_INIT; pthread_once(&s_once, tb_thread_local_init); //Try to read the current tls data tb_size_t local; if (! (local = (tb_size_t)pthread_getspecific(g_local_key))) { //Set the tls data as the current thread id tb_size_t self = tb_thread_self(); if (0 == pthread_setspecific(g_local_key, (tb_pointer_t)self)) local = self; } return 0; }
TlsSetValue interface
static tb_int_t tb_thread_local_test(tb_cpointer_t priv) { //Create a tls key. Note: This is not thread safe. It is better to create it in the init function provided by pthread_once //This is written here for the time being, just to facilitate the description of api usage, don't copy it.. static DWORD s_key = 0; if (! s_key) s_key = TlsAlloc(); //Try to read the current tls data DWORD local; if (! (local = TlsGetValue(s_key))) { //Set the tls data as the current thread id tb_size_t self = tb_thread_self(); if (TlsSetValue(s_key, (LPVOID)self)) local = self; } return 0; }
Provided by tbox thread_local
Interface encapsulation
-
Support the registration of automatic release callbacks to ensure that the set tls data is automatically released when the thread exits -
Support thread safe key creation within threads -
When tbox exits, it will automatically destroy all created keys. Of course, you can also actively destroy it in advance
static tb_void_t tb_demo_thread_local_free(tb_cpointer_t priv) { tb_trace_i("thread[%lx]: free: %p", tb_thread_self(), priv); } static tb_int_t tb_demo_thread_local_test(tb_cpointer_t priv) { /*Thread safely initialize a tls object, equivalent to a key, and register an automatic free callback * *Note: Although all threads will execute to this tb_thread_local_init *However, the tls object of s_local will only be initialized once. There is an internal pthread_once interface to maintain */ static tb_thread_local_t s_local = TB_THREAD_LOCAL_INIT; if (! tb_thread_local_init(&s_local, tb_demo_thread_local_free)) return -1; //Try to read the current tls data tb_size_t local; if (! (local = (tb_size_t)tb_thread_local_get(&s_local))) { //Set the tls data as the current thread id tb_size_t self = tb_thread_self(); if (tb_thread_local_set(&s_local, (tb_cpointer_t)self)) local = self; } return 0; }
Miscellaneous talk
static __thread pthread_key_t g_key;
summary