linux unnamed posix semaphore sem_destroy, sem_wait method question - linux

when there are waiting semaphores of sem_wait method, I call the sem_destroy method on other thread. But waiting semaphore was not wake up.
In case of mutex, pthread_mutex_destroy was return the value EBUSY when there are some waiting threads.
however sem_destroy return 0 and errno was also set 0.
I want to destroy semaphore after calling sem_destroy to block access as destroyed semaphore and to wake up the waiting thread.
Semaphore handle of Window OS is possible.
please advise me. thank you.

POSIX says this about sem_destroy:
The effect of destroying a semaphore upon which other threads are currently blocked is undefined.
It specifically doesn't say that other threads are woken up. In fact, if sem_t contains a pointer to memory, what it almost certainly does do is free the memory, meaning you then have a use-after-free security problem. (Whether that is the case depends on your libc.)
The general approach of allocation for mutexes and semaphores is that they should be either allocated and freed with their relevant data structure, or they should be allocated before the relevant code needs them and then freed after the entire code is done with them. In C, you cannot safely deallocate data structures (e.g., with sem_destroy) that are in use.
If you want to wake up all users of the semaphore, you must increment it until all users have awoken. You can call sem_getvalue to determine if anyone is waiting on the semaphore and then call sem_post to increment it. Only then can you safely destroy it. Note that this can have a race condition, depending on your code.
However, note that you must be careful that the other code does not continue to use the semaphore after it's destroyed, such as by trying to re-acquire it in a loop. If you are careful to structure your code properly, then you can have confidence that this won't happen.

Related

Can it be assumed that `pthread_cond_signal` will wake the signaled thread atomically with regards to the mutex bond to the condition variable?

Quoting POSIX:
The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal().
"If predictable scheduling behavior is required". This could/would hint that locking the mutex bound to the condition variable right before calling pthread_cond_signal() should guarantee that the signaled thread will be woken up before any other thread manages to lock this mutex. Is this correct?
We will se if any PThreads guru has a more comprehensive answer, but as far as I can see, at least in the Linux manpage, you do not get fully predictable behavior. What you do get is a guarantee that if two threads wait on the same condition variable, the higher-prio thread gets to go first (at least, that should be true on Linux if one thread is SCHED_OTHER and the other is real-time SCHED_FIFO). That holds if you lock mutex before signalling (with reservation for errors after a quick read of the manpage).
See
https://linux.die.net/man/3/pthread_cond_signal
No, there is no guarantee the signalled thread will be waken up. Worse, if in the signalling thread you have sequence:
while(run_again) {
pthread_mutex_lock(&mutex);
/* prepare data */
pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cond);
}
there is reasonable chance control would never be passed to other threads waiting on mutex because of logic in the scheduler. Some examples to play with you can find in this answer.
No.
The best reference I have found regarding the predictability is this one:
https://austin-group-l.opengroup.narkive.com/lKcmfoRI/predictable-scheduling-behavior-in-pthread-cond-broadcast
Basically, people want to guard against the possibility that threads do not get a fair chance to run. Apparently, it is not a problem for most producer-consumer scenarios, and it does not apply to pthread_cond_broadcast as well. I would say, it is useful only in limited cases.
Cppreference.com actually considers unlocking after notifying may be a pessimization:
https://en.cppreference.com/w/cpp/thread/condition_variable/notify_all

Mutex and signal() and wait() operations

I have two question about mutexes:
1. When a mutex variable equals to 1, and we do a signal() operation on it, what is expected to happen?
2. When mutex equals to 0, and we do a wait(), then the thread is blocked, and mutex stays 0. correct? After a while, another thread makes a signal() operation, then the blocking is released. What will be the value of the mutex now? 0 or 1?
So conceptually mutex has 2 states: locked and unlocked. If it is represented by 0 or 1 is not important here.
If you unlock (i.e. signal) a mutex it changes its state from locked to unlocked. Further unlocking doesn't change its state and it actually doesn't do anything.
If a mutex is unlocked and you call wait then the call does nothing (it does not wait) and the thread continues its execution.
When a mutex is locked and you call wait then the thread is blocked. When other thread calls unlock then blocking is released and the mutex becomes unlocked.
The most important thing is that unlock and lock operations are atomic in the sense that parallel calls cannot overlap each other to produce corrupted result (formally: parallel calls to lock/unlock are always equivalent to some serialized call history). Otherwise the whole concept of mutex would be simply stupid. :)
After reading the comments (and original unedited question) it is clear that there is enough people out there who believe binary sempahores to be interchangeable with mutexes. If we speak in practical terms (that is, pthread mutex and System V semaphore) they are very different. I will try to outline the most important differences below.
Conceptual ownership. Mutexes are owned by their locker, sempahores are not owned by anybody. This leads to two disticntions. Very important one is that mutexes can (should) only be unlocked by the owner (locker thread), while sempahores can be unlocked by any thread (see below for permissions). The less important thing is that mutexes can be made re-entrant - that is, can be locked multiple times with the owner thread - while semaphores can't behave so. I say it is less important because reentrant mutexes almost always present design flaw.
Semaphores are objects which are more or less indepenent of the user. They can be created, used and destroyed by completely unrelated processess or threads, which do not even have to know anything of each other (or execute at the same time). For example, a process might create a semaphore and than die, and other processes can use it, while third process will remove it). Semaphores have permissions associated with them (not unlike file permissions), while mutexes have no such thing - anybody who have access to mutex technically can do anything with it.
Semaphores are process-shared. That is, they can be used by multiple processes without extra efforts. Default mutexes are single-process only, if the same mutex is to be used by multiple processes, it has to be created in a special mode.

pthread rwlock lock/unlock from different threads

The docs says that locking from a thread and unlocking from another a rwlock results in undefined behaviour. I have an array and two threads, one allocating it and one deallocating it, this happens in a cycle, and there are also some threads reading/writing in it, but they never overlap so no synchronization is needed there. The problem is the read/write threads still try to use the array in the timeframe between dealloc - alloc. I was thinking of using a read lock for the read/write threads and lock the array for writing in the dealloc thread and unlocking writing in alloc thread. But this results in undefined behavior since they happen on different threads. What would be the right approach in this case?
You need some variable that stores the state. You can protect that variable with a lock. So when a thread needs to check or change the state, it acquires the lock, checks or changes the state, and then releases the lock.

Know how many are waiting on a pthread mutex lock

I would like to know how many threads are waiting on a lock so I would be able to destroy it safely.
The problem is that I can't destroy the lock when someone holds it or someone is waiting on it.
My program can make sure that no new requests are made to acquire the lock, but how can I know when all the threads that waited on it are done with it?
I thought about a conditional variable but I suspect it will create problems..
dlv, could you add some code snippet to your description.
I hope you should be using condition variables,
Each thread will block in pthread_cond_wait() until the other thread signals it to wake up. This will not cause a deadlock. It can easily be extended to many threads, by allocating one int, pthread_cond_t and pthread_mutex_t per thread.
pthread_cond_wait() blocks the calling thread until the specified condition is signalled. This routine should be called while mutex is locked, and it will automatically release the mutex while it waits. After signal is received and thread is awakened, mutex will be automatically locked for use by the thread. The programmer is then responsible for unlocking mutex when the thread is finished with it.
The pthread_cond_signal() routine is used to signal (or wake up) another thread which is waiting on the condition variable. It should be called after mutex is locked, and must unlock mutex in order for pthread_cond_wait() routine to complete.
The pthread_cond_broadcast() routine should be used instead of pthread_cond_signal() if more than one thread is in a blocking wait state.
It is a logical error to call pthread_cond_signal() before calling pthread_cond_wait().
Proper locking and unlocking of the associated mutex variable is essential when using these routines. For example:
Failing to lock the mutex before calling pthread_cond_wait() may cause it NOT to block.
Failing to unlock the mutex after calling pthread_cond_signal() may not allow a matching pthread_cond_wait() routine to complete (it will remain blocked).
If threads that can use the mutex still exist or might be created in the future then don't delete it.
You do know and are tracking what threads are created, right?
If, for some reason, you cannot keep track of the threads using a resource, your only way out is to leak the resource. It can never be safely deleted because you never know when you are done using it.
Say you had a counter that counted the threads using a mutex. That counter would need its own mutex. Then how do you decide when to delete that one?
That way of thinking is the road that leads to hell. You could do what you want with condition variables, but the result would be an extremely weak design.
Assuming you managed to create such a monster, it would basically allow you to kill "safely" any other thread regardless of its internal state. Except for a quick and dirty panic exit (in case of some internal software error), this is the worst possible way of solving synchronization issues.
A design relying on such tricks would have to create implicit synchronizations between tasks to make sure the terminations occur in the proper order. A lot of software are designed that way, and most of them allow mediocre programmers to make a living by maintaining the pile of crap they created in the first place.
Task termination should be an issue solved at global design level, not by a toolbox of wonky objects that allow you to twist synchronization any odd way.

Can multithreaded code possible deadlock be avoided this way?

We know that multi-threaded code has the bane of possible deadlocks if the threads acquire mutex locks but before it gets a chance to release it, the thread gets suspended by main thread or pre-empted out by Scheduler?
I am a beginner in using pthread library so please bear with me if my below query/proposed solution might be unfeasible or outright wrong.
void main()
{
thread_create(T1,NULL,thr_function,NULL)
suspend_thread(T1);
acquire_lock(Lock1);<--- //Now here is a possible deadlock if thread_function acquried Lock1 before main and main suspended T1 before its release
//Do something further;
}
void *thr_function(void *val)
{
///do something;
acquire_lock(Lock1);
//do some more things;
//do some more things;
release_lock(Lock1);
}
In this below pseudo code segment above I have, can't the thread run-time/compiler work together to make sure if a thread which has acquired a mutex lock, is suspended/pre-empted then it executes some 'cleanup code' of releasing all locks it has held before it gets out. The compiler/linker can identify the places inside a thread function which acquire , release lock, then when a thread is suspended between those two places(i.e. after acquire but before release) the execution in the thread function should jump via some kind of 'goto label;' inserted by the runtime where at the label: the thread would release the lock and then the thread gets blocked or context switch happens. [ I know if a thread acquires more than 1 locks it might get messy to jump across those points to release those locks...]
But basic idea/question is can the thread function not do the necessary releases of acquired locks for mutexes, semaphores before it gets blocked out or goes out of execution state to wait or some other state?
No. The reason a thread holds a lock is so that it can make data temporarily inconsistent or see a consistent view of that data itself. If some scheme were to automatically release that lock before the thread made the data consistent again, other threads would acquire the lock, see the inconsistent data, and fail. Or when that thread was resumed, it would either not have the lock or have the lock and see inconsistent data itself. This is why you can only reliably suspend a thread with that thread's cooperation.
Consider this logic to add an object to a linked list protected by a mutex:
Acquire the lock protecting a linked list.
Modify the link's head pointer.
Modify the object's next pointer.
Release the lock.
Now imagine if something were to suspend the thread between steps 2 and 3. If the lock were released, other threads would see the link's head pointer pointing to an object that had not been linked to the list. And when the thread resumed, it might set the object to the wrong pointer because the list had changed.
The general consensus is that suspending threads is so evil that even a feeling that you might want to suspend a thread suggests an incorrect application design. There is practically no reason a properly-designed application would ever want to suspend a thread. (If you didn't want that thread to continue doing the work it was doing, why did you code it to continue doing that work in the first place?)
By the way, scheduler pre-emption is not a problem. Eventually, the thread will be scheduled again and release the lock. So long as there are other threads that can make forward progress, no harm is done. And if there are no other threads that can make forward progress, the only thing the system can do is schedule the thread that was pre-empted.
One way to avoid this kind of deadlocks is to have a global, mutexed variable should_stop_thread which eventually gets set to true by the master thread.
The child thread checks the variable regularly and terminates in a controlled manner if it is true. "Controlled" in this sense means that all data (pointers) are valid (again) and mutex locks are released.

Resources