[Concurrent concurrency] _ [C/C ++] _ [Use Thread Local Storage (TLS)-comparison between win32 and pthread],-win32pthread
Scenario:
1. count the number of objects created on a thread.
2. When the created heap space needs to be created and destroyed Based on thread needs.
3. because the range is that the thread can only view its own stored data, it does not need to maintain its own heap memory in the critical section or mutex. if the global std: map is used for implementation, the lock must be applied to put and get, which consumes resources.
4. It can be used to maintain a connection, such as a socket or database connection.
Note:
1. Java also has its own thread to locally store ThreadLocal
2. win32 version of pthread: http://sourceware.org/pthreads-win32/
Example test_TSL.cpp:
# Include "stdafx. h "# include <stdio. h> # include <stdint. h> # include <stdlib. h> # include <assert. h> # include <windows. h> # include "pthread. h "# define THREADCOUNT 4 DWORD dwTlsIndex; VOID ErrorExit (const char *); static partition barrier = NULL; static partition = PTHREAD_ONCE_INIT; static pthread_key_t key; VOID CommonFunc (VOID) {LPVOID lpvData; // Retrieve a data pointer For the current thread. lpvData = TlsGetValue (dwTlsIndex); if (lpvData = 0) & (GetLastError ()! = ERROR_SUCCESS) ErrorExit ("TlsGetValue error"); // Use the data stored for the current thread. int64_t * value = (int64_t *) lpvData; printf ("common: thread % d: lpvData = % lx: value = % lld \ n", GetCurrentThreadId (), lpvData, * value); Sleep (5000);} dword winapi ThreadFunc (VOID) {LPVOID lpvData; // Initialize the TLS index for this thread. lpvData = (LPVOID) LocalAlloc (LPTR, 8); if (! TlsSetValue (dwTlsIndex, lpvData) ErrorExit ("TlsSetValue error"); int64_t * value = (int64_t *) lpvData; * value = GetCurrentThreadId (); printf ("thread % d: lpvData = % lx \ n ", GetCurrentThreadId (), lpvData); CommonFunc (); // Release the dynamic memory before the thread returns. lpvData = TlsGetValue (dwTlsIndex); if (lpvData! = 0) LocalFree (HLOCAL) lpvData); return 0;} void TestWin32TLS () {DWORD IDThread; HANDLE hThread [THREADCOUNT]; int I; // Allocate a TLS index. if (dwTlsIndex = TlsAlloc () = TLS_OUT_OF_INDEXES) ErrorExit ("TlsAlloc failed"); // 1. note that dwTlsIndex does not start from 0. printf ("dwTlsIndex % ld \ n", dwTlsIndex); // Create multiple threads. for (I = 0; I <THREADCOUNT; I ++) {hThread [I] = CreateThread (NULL, // default security attributes 0, // use default stack size (LPTHREAD_START_ROUTINE) threadFunc, // thread function NULL, // no thread function argument 0, // use default creation flags & IDThread); // returns thread identifier // Check the return value for success. if (hThread [I] = NULL) ErrorExit ("CreateThread error \ n") ;}for (I = 0; I <THREADCOUNT; I ++) waitForSingleObject (hThread [I], INFINITE); TlsFree (dwTlsIndex);} void CommonFuncPthread (void) {void * lpvData = pthread_getspecpacific (key); int64_t * value = (int64_t *) lpvData; printf ("common: thread % d: lpvData = % lx: value = % lld \ n", GetCurrentThreadId (), lpvData, * value );} void * StartPthread (void * data) {int64_t * buf = (int64_t *) malloc (256); * buf = GetCurrentThreadId (); pthread_setspecpacific (key, buf); CommonFuncPthread (); free (buf); pthread_barrier_wait (& barrier); return NULL;} // 1. it can be called only once, and can be placed in a random work thread execution function. A thread will be randomly located for execution. // 2. similar to win32 DLL_PROCESS_ATTACH, it is only executed once. void TestPthreadTLS () {pthread_key_create (& key, NULL); pthread_barrier_init (& barrier, NULL, THREADCOUNT + 1); for (int I = 0; I <THREADCOUNT; ++ I) {pthread_t; pthread_create (& t, NULL, StartPthread, NULL); pthread_detach (t);} // 1. wait until the execution of other threads is complete. pthread_barrier_wait (& barrier); pthread_key_delete (key);} DWORD main (VOID) {// 1. win32TLS printf ("TestWin32TLS \ n"); TestWin32TLS (); // 1. pthread TLS printf ("TestPthreadTLS \ n"); TestPthreadTLS (); return 0;} VOID ErrorExit (const char * lpszMessage) {fprintf (stderr, "% s \ n ", lpszMessage); ExitProcess (0 );}
.
Output:
TestWin32TLSdwTlsIndex 26thread 8452: lpvData=714f50common: thread 8452: lpvData=714f50 : value=8452thread 8460: lpvData=7153d0common: thread 8460: lpvData=7153d0 : value=8460thread 8456: lpvData=715610common: thread 8456: lpvData=715610 : value=8456thread 8464: lpvData=715190common: thread 8464: lpvData=715190 : value=8464TestPthreadTLScommon: thread 8520: lpvData=3b4eb0 : value=8520common: thread 8512: lpvData=3b4ff0 : value=8512common: thread 8516: lpvData=3b4eb0 : value=8516common: thread 8524: lpvData=3b4ff0 : value=8524
Refer:
Https://msdn.microsoft.com/en-us/library/windows/desktop/ms686749 (v = vs.85). aspx
Https://msdn.microsoft.com/en-us/library/windows/desktop/ms686991 (v = vs.85). aspx
Http://blog.chinaunix.net/uid-10231348-id-3034751.html
Http://blog.csdn.net/liulina603/article/details/17991731
Http://linux.die.net/man/3/pthread_once