How exactly i can destroy a pthread mutex variable ?
Here is what i want to do. I want to have objects (structure variables) cached , which are looked up by key. I want
I want to free the object from the cache. Now how to destroy/free mutex correctly ? pthread_mutex_destroy document says we should not use the pthread_mutex_destroy while the mutex is locked. Lets say a thread decides to destroy the object it needs to destroy the lock so it releases the lock and does a pthread_mutex_destroy. What happens to the other threads waiting for the objects lock ?
Well I hope I get your intention right, I had the exact same problem. Anyway I realized, later that I was stupid: Complaining about undefined behaviour of pthread_mutex_*
functions after pthread_mutex_destroy()
is like complaining about SEGFAULTS
when accessing a pointer after free()
.
Most C programs are modelled around the paradigm that every program must make sure that memory is not accessed after some sort of destruction. Good C programs will have a design that prevents pointers from being spread everywhere, so that destruction happens only at well defined places, when no other variable contains a pointer anymore. This is not at all a concern in garbage collected languages.
Solution 1: Use refcounting like it is done for memory allocation. The refcounter is accessed via atomic functions. (Use the glib, it contains great, portable stuff)
Solution 1b: Use refcounting like it is done for memory allocation, sperate the kinds of workers that are important from those that aren't and use weak references in the later so that they do not prevent object destruction.
Solution 2: Do not destroy the mutex. Why bother with saving RAM? Just make a global static array of like 128k objects. Add a struct member wich indicates the state of the object. Instead of destruction just atomic compare and set the state variable, and print an error in the threads that access an object in "DISABLED" state.
Solution 3 - The hard way: Don't do shared memory concurrency. Combine a thread pool which matches the number of CPUs on the system, use non-blocking IO, message objects and state-machine design. Make message queues for each task, and let tasks communicate only by messages enqueued in the queue of the other. Put the queue in the same 'select' or 'pollfd' set that contains the sockets/filedescriptors. To shuffle big data (3d game) between state machines, use a struct with an atomic refcounter and copy on write semantics. This will in most cases be the most performant, stable and maintainable solution.
If what you do has anything to do with performance, think twice about using the atomic operations. They can be more expensive than mutexes.