Destroying Static Class Members in a Local Thread Storage

I am writing a program with fast multi-threaded thread and I want to avoid synchronization (the function that needs to be synchronized should be called approximately 5,000,000 times per second, so even the mutex will be too heavy).

Scenario: I have one global instance of the class, and each thread can access it. To avoid synchronization, all data within the class is read-only, with the exception of a group of class members, which are then declared in TLS (with __thread or __declspec (thread)).

Unfortunately, to use the __thread interface offered by the compiler, class members must be static and without constructors / deconstructors. Of course, the classes I use have custom constructors, so I declare a pointer to these classes as members of the class (something like a static __thread MyClass * _object).

Then, when the thread calls the method from the global instance, I will do something like "(if _object == NULL) object = new MyClass (...)".

My biggest problem: is there a smart way to free allocated memory? This global class is from the library and is used by many threads in the program, and each thread is created differently (i.e., each thread performs a different function), and I cannot put a snipplet of code every time the thread stops. Thanks guys.

+5
source share
5 answers

TLS flushing is usually done in DllMain when it is passed DLL_THREAD_DETACH.

If your code is in an EXE, and not in a DLL, you can create a dummy DLL loaded by the EXE, which in turn will call the DLL_THREAD_DETACH into the EXE. (I do not know how best to work with the EXE code at the end of the stream.)

There are several ways that a DLL can call back to an EXE: one of them is that the EXE can export functions like DLLs, and the DLL can use GetProcAddress to handle the EXE module. An easier way is to provide the DLL with an init function that the EXE calls to explicitly pass the function pointer.

, , DllMain, (, , ), , . ; , API kernel32.dll, HeapAlloc, TLS.

, DLL_THREAD_ATTACH , , DLL ( DLL_THREAD_DETACH, DLL), () DLL_PROCESS_DETACH, .

+2

, boost thread_specific_ptr. , , . - , , . pthread pthread_key_create pthreads.


, , , , . , . , .

. pthreads, pthread_cleanup_push. , . , , . , -, . . , , , , .

, . : . . , : , , .

, , ( boost bind, shared_ptr, ).

.

+2

+1

++ 11 :

static thread_local struct TlsCleaner {
    ~TlsCleaner() {
        cleanup_tls();
    }
} tls_cleaner;

cleanup_tls() ( ++ API, std::thread).

TLS ( ). : static thread_local std::unique_ptr<MyClass> pMyClass; MyClass, .

Prior to C ++ 11, you can use hacks such as GNU or MSVC link builders _ tls_used callback.

Or, starting with Windows 6 (Vista), FlsAlloc , which accepts a cleanup callback.

+1
source

All Articles