[Concurrent parallel] _ [C/C ++] _ [use a Thread to locally store Thread Local Storage (TLS) to call the copy file interface]
Use Cases:
1. When copying a file, a thread generally calls an interface to copy the file. At this time, data needs to be cached. If each file needs to create an independent cache, the memory fragmentation is very large.
If a static memory zone is created and multiple threads call the same interface using the same static cache at the same time, data pollution may occur. the best way is that the cache is only visible to this thread,
When a thread is created, the cache area is created and destroyed when the thread ends.
2. There are comments in the Code:
Test. cpp
# Include
# Include pthread. h # include
# Include
Typedef enum kTLSKey1 {token = 0, kTLSKeyOthers, kTLSKeyMax} kTLSKey; static pthread_key_t gTLSKey [kTLSKeyMax]; static int gTLSKeySize [kTLSKeyMax] = {token }; // This is only used for testing and waiting for all threads to end. It has nothing to do with TLS. static pthread_barrier_t barrier = NULL; static int THREADCOUNT = 10; // interface 1 void StartWork (kTLSKey type) {pthread_key_t & key = gTLSKey [type] provided by our custom library; pthread_key_create (& key, NULL) ;}// interface 2 void EndWork (kTLSKey type) {pthread_key_t & key = gTLSKey [type] provided by our custom library; pthread_key_delete (key);} // The Interface 3/data parameter provided by our custom database is only used to prove that the TLS variable is bound to the thread. void MyCopyFile (const char * from, const char * to, void * data) {pthread_key_t & key = gTLSKey [kTLSKeyCopyFileBuf]; char * lpvData = (char *) pthread_getspecific (key ); assert (lpvData = data); Sleep (100);} void * ThreadFunc (void * data) {int size = gTLSKeySize [kTLSKeyCopyFileBuf]; pthread_key_t & key = gTLSKey [secret]; char * buf = (char *) malloc (size); std: cout <GetCurrentThreadId () <Create buf size: <size <: <(int *) buf <std: endl; pthread_setspecific (key, buf); // The requested memory is stored in TLS. // each thread copies 100 files for (int I = 0; I <100; ++ I) {MyCopyFile (C: \ infoworld.txt, E: \ infoworld.txt, buf );} free (buf); std: cout <ThreadFunc: <GetCurrentThreadId () <finish <std: endl; pthread_barrier_wait (& barrier); return NULL ;} void TestPthreadLocalStorage () {StartWork (kTLSKeyCopyFileBuf); // initialize it in the main program. pthread_barrier_init (& barrier, NULL, THREADCOUNT + 1); // The main thread is also, so + 1 // simulate THREADCOUNT threads and call the interface MyCopyFile at the same time. for (int I = 0; I <THREADCOUNT; ++ I) {pthread_t; pthread_create (& t, NULL, ThreadFunc, NULL); pthread_detach (t );} pthread_barrier_wait (& barrier); EndWork (kTLSKeyCopyFileBuf); // release it in the main program .} int main (int argc, char const * argv []) {setvbuf (stdout, NULL, _ IONBF, 0); std: cout <test thread local storage. <std: endl; TestPthreadLocalStorage (); std: cout <end thread local storage. <std: endl; return 0 ;}
Output:
test thread local storage.5168 Create buf size: 4194304:0x11800203892 Create buf size: 4194304:0x17900203352 Create buf size: 4194304:0x21a00205808 Create buf size: 4194304:0x29b00204972 Create buf size: 4194304:0x2dc00206812 Create buf size: 4194304:0x31d00206132 Create buf size: 4194304:52200x35e0020 Create buf size: 4194304:0x39f00206124 Create buf size: 4194304:0x3e000206864 Create buf size: 4194304:0x4210020ThreadFunc: 5168 finishThreadFunc: 3892 finishThreadFunc: 6812 finishThreadFunc: 5220 finishThreadFunc: 4972 finishThreadFunc: 6132 finishThreadFunc: 6864 finishThreadFunc: 3352 finishThreadFunc: 5808 finishThreadFunc: 6124 finishend thread local storage.