If a thread is sleeping/waiting, can it still be preempted? - linux

Is there any way to tell if a thread is sleeping/waiting by monitor/lock/synchronization mechanism, can it still be preempted?

Related

Check which thread has locked a QMutex

I am facing a weird deadlock when doing something in our database program. The critical point is when thread tries to lock a QMutex:
QMutexLocker locker(&tableMutex_);
That makes the program go stuck.
I'm baffled, because no other thread - AFAIK - has access to this mutex. What I want to do now is to figure out which thread has locked it. How could I do that?
Interrupt your hanging program in a debugger and examine the stack traces of all threads.

How spinlocked threads avoid overhead of context switching?

In wikipedia, the aritcle about spinlocks.
Because they avoid overhead from operating system process rescheduling or context switching, spinlocks are efficient if threads are likely to be blocked for only short periods.
I actually can't grasp this sentence.
I think that even if a thread has a spinlock, it's going to be rescheduled, am I wrong ?
The context switching over-head - which is saving the registers,pc & scheduling queue - is constant for all switches, isn't it?
I actually can't grasp this sentence. I think that even if a thread
has a spinlock, it's going to be rescheduled, am I wrong ?
Eventually it would be... when its timeslice expired.
What a spinlock avoids is the chance of having the thread get context-switched out immediately whenever it tries to acquire and the lock is already locked by another thread.
(In the traditional mutex case, when the mutex is already locked, the thread would immediately be put to sleep aka context-switched out, and it would not be reawoken until after the other thread had unlocked the mutex. In spinlock case, OTOH, the thread would just keep checking the spinlock's state in a tight loop, until the spinlock was no longer locked, and then the thread would lock the spinlock for itself. Note that at no point during that process would the thread ask the kernel to put the thread to sleep, although if it spun for a long time its possible the kernel would do anyway... but a program using spinlocks will hopefully never lock them for a long time anyway, since spinning is really inefficient)
The context switching over-head - which is saving the registers,pc &
scheduling queue - is constant for all switches, isn't it?
Yes, I believe it is.
Generally an OS is only going to use spinlocks in interrupt service routines. These are designed to be of short duration.
I actually can't grasp this sentence. I think that even if a thread has a spinlock, it's going to be rescheduled, am I wrong ?
Not while it is handling an interrupt (simplifying here that only there is only one IPL). That interrupt might be the timer interrupt where the a context switch may take place. However, in that situation, the spinlock wait would be for the resources necessary to process a context switch.

Can a thread be logically interruptible while waiting for a mutex?

I was reading R&R's Unix system programming, I encounter a question about mutex. For the following paragraph stated in that book. When he said a thread that waits for a mutex is not logically interruptible, does it mean when a thread wait for a mutex, it won't be able to do a context switch? Can someone elaborate it?
A thread that waits for a mutex is not logically interruptible except
by termination of the process, termination of a thread with
pthread_exit (from a signal handler), or asynchronous cancellation
(which is normally not used).
No, it doesn't mean that it can't context switch. On the contrary, a thread waiting for a mutex that is already acquired almost always will context switch away, perhaps after a short delay.
All it means is that the pthread_mutex_lock() call won't return EINTR or similar - it will either successfully acquire the mutex, or return persistent failure.

On linux, how to make sure to unlock a mutex which was locked in a thread that dies/terminates?

This is an interview question.
On linux, how to make sure to unlock a POSIX mutex which was locked in a POSIX thread that dies/terminates?
My idea:
Linux will release it automatically when it send kill or termination signal to the program ? But, I cannot find more details about how OS do this ?
thanks
A robust mutex can be used to handle the case where the owner of the mutex is terminated while holding the mutex lock, so that a deadlock does not occur. These have more overhead than a regular mutex, and require that all clients locking the mutex be prepared to handle the error code EOWNERDEAD. This indicates that the former owner has died and that the client receiving this error code is the new owner and is responsible for cleaning up any inconsistent state.
A robust mutex is a mutex with the robust attribute set. It is set using the POSIX.1-2008 standard function pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST).
Further details and example code can be found on the Linux manual page for pthread_mutexattr_getrobust.
If it's not a process-shared mutex, it doesn't matter. When one thread dies, the process dies, and the mutex goes away.
If it's a process-shared mutex, you're asking the wrong question. You wouldn't want to unlock the mutex if a thread died while holding it. The reason a thread holds a mutex is so that it can manipulate shared data through states that must not be seen by other threads. If a thread dies while holding a mutex, it is likely that the data was left in such an inconsistent state. Unlocking the mutex would just allow other threads to see the invalid/corrupt data.

synchronising threads with mutexes

In Qt, I have a method which contains a mutex lock and unlock. The problem is when the mutex is unlock it sometimes take long before the other thread gets the lock back. In other words it seems the same thread can get the lock back(method called in a loop) even though another thread is waiting for it. What can I do about this? One thread is a qthread and the other thread is the main thread.
You can have your thread that just unlocked the mutex relinquish the processor. On Posix, you do that by calling pthread_yield() and on Windows by calling Sleep(0).
That said, there is no guarantee that the thread waiting on the lock will be scheduled before your thread wakes up again.
It shouldn't be possible to release a lock and then get it back if some other thread is already waiting on it.
Check that you actually releasing the lock when you think you do. Check that waiting thread actually waits (and not spins a loop with a trylock tests and sleeps, I actually done that once and was very puzzled at first :)).
Or if waiting thread really never gets time to even reach locking code, try QThread::yieldCurrentThread(). This will stop current thread and give scheduler a chance to give execution to somebody else. Might cause unnecessary switching depending on tightness of your loop.
If you want to make sure that one thread has priority over the other ones, an option is to use a QReadWriteLock. It's adapted to a typical scenario where n threads are going to read a value in a infinite loop, with only one thread updating it. I think it's the scenario you described.
QReadWriteLock offers two ways to lock: lockForRead() and lockForWrite(). The threads depending on the value will use the latter, while the thread updating the value (typically via the GUI) will use the former (lockForWrite()) and will have top priority. You won't need to sleep or yield or whatever.
Example code
Let's say you have a QReadWrite lock; somewhere.
"Reader" thread
forever {
lock.lockForRead();
if (condition) {
do_stuff();
}
lock.unlock();
}
"Writer" thread
// external input (eg. user) changes the thread
lock.lockForWrite(); // will block as soon as the reader lock ends
update_condition();
lock.unlock();

Resources