Usage scenarios:
1. When copying files, it is common for a thread to call an interface to copy files, which requires caching the data, and if each file needs to create a separate cache, the memory fragmentation is large.
If you create a static memory area, when multithreading calls the same interface, multiple threads using the same static cache can cause data pollution. The best way is that the cache is visible only to this thread,
Creates a buffer when the thread is created and destroys the buffer when the thread ends.
2. There are comments in the code:
Test.cpp
#include <iostream> #include "pthread.h" #include <assert.h> #include <Windows.h> #include < stdio.h>typedef enum ktlskey1{ktlskeycopyfilebuf = 0,ktlskeyothers,ktlskeymax}ktlskey;static pthread_key_t gtlskey[ktlskeymax];static int Gtlskeysize[ktlskeymax] = {4194304,4096};//This is just a test waiting thread all over, and TLS has nothing to do with it. Static Pthread _barrier_t barrier = NULL; static int threadcount = 10;//Our custom library provides interface 1void startwork (ktlskey type) {pthread_key_t& key = Gtlskey[type];p thread_ Key_create (&key,null);} Our custom library provides interface 2void endwork (ktlskey type) {pthread_key_t& key = Gtlskey[type];p thread_key_delete (key);} Our custom library provides an interface 3//the data parameter just to prove that the variable of TLS is a bound thread. void Mycopyfile (const char* from, const char* to,void* data) {pthread_key_t& Amp Key = gtlskey[ktlskeycopyfilebuf];char* Lpvdata = (char*) pthread_getspecific (key); assert (Lpvdata = = data); Sleep (100);} void* ThreadFunc (void* data) {int size = Gtlskeysize[ktlskeycopyfilebuf];p thread_key_t& key = gtlskey[ ktlskeycopyfilebuf];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.//Copy 100 files per thread for (int i = 0; i < ++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);//In the main program initialization. Pthread_barrier_init (&barrier,null, THREADCOUNT+1); The main thread is also, so +1//simulates threadcount threads simultaneously calling interface Mycopyfile.for (int i = 0; i < ThreadCount; ++i) {pthread_t T; Pthread_create (&t,null,threadfunc,null); Pthread_detach (t);} Pthread_barrier_wait (&barrier); Endwork (KTLSKEYCOPYFILEBUF); Released 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 si ze:4194304:0x21a00205808 Create buf size:4194304:0x29b00204972 create buf size:4194304:0x2dc00206812 create BUF size:4 194304:0x31d00206132 Create buf size:4194304:52200x35e0020 create buf size:4194304:0x39f00206124 create BUF size:419430 4: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.
Complete project:
http://download.csdn.net/detail/infoworld/9251421
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
[Concurrent parallel]_[c/c++]_[uses thread-local storage threads locally Storage (TLS) calls to copy a file interface case]