I had the same problem as yours: pthread_setspecific sets the key, but the destructor is never called. To fix this, we simply switched to thread_local in C ++. You can also do something like this if this change is too complicated:
For example, suppose you have some ThreadData class that you want to perform some action when the thread completes. You define a destructor for something in these lines:
void destroy_my_data(ThreadlData* t) { delete t; }
When your thread starts, you allocate memory for the ThreadData* instance and assign it a destructor as follows:
ThreadData* my_data = new ThreadData; thread_local ThreadLocalDestructor<ThreadData> tld; tld.SetDestructorData(my_data, destroy_my_data); pthread_setspecific(key, my_data)
Note that ThreadLocalDestructor defined as thread_local. We rely on the C ++ 11 mechanism, which, when exiting the stream, automatically calls the ThreadLocalDestructor destructor, and ~ThreadLocalDestructor is implemented to call the destroy_my_data function.
Here is the implementation of ThreadLocalDestructor:
template <typename T> class ThreadLocalDestructor { public: ThreadLocalDestructor() : m_destr_func(nullptr), m_destr_data(nullptr) { } ~ThreadLocalDestructor() { if (m_destr_func) { m_destr_func(m_destr_data); } } void SetDestructorData(void (*destr_func)(T*), T* destr_data) { m_destr_data = destr_data; m_destr_func = destr_func; } private: void (*m_destr_func)(T*); T* m_destr_data; };
source share