In multi-threaded applicatoin;
Why do we need to lock() before we wait()? What could go wrong if we didn't lock()?
This question is similar to why wait() and notify() method should be called inside synchronized block,because to enter in synchronized block the thread first needs the lock on the object then only It can enter in the block.
wait() and notify() are basically two methods for inter-thread communication, so If a thread want to wait on a object for some condition to be fulfilled before proceeding further, so It can call wait() and then some other thread when fulfilled that condition then that thread will call notify() on the same object to notify the previously waiting thread. Actually Its a very common question. I will suggest you once go through below links, to clear your doubts and make your concept clearer.
http://javarevisited.blogspot.com/2011/05/wait-notify-and-notifyall-in-java.html
Why must wait() always be in synchronized block
Related
My thread does not need to be locked. std::unique_lock locks thread on construction. I am simply using cond_var.wait() as a way to avoid busy waiting. I have essentially circumvented the auto-locking by putting the unique_lock within a tiny scope and hence destroying the unique lock after it leaves the tiny scope. Additionally, there is only a single consumer thread if that's relevant.
{
std::unique_lock<std::mutex> dispatch_ul(dispatch_mtx);
pq_cond.wait(dispatch_ul);
}
Is there possibly a better option to avoid the unnecessary auto-lock functionality from the unique_lock? I'm looking for a mutexless option to simply signal the thread, I am aware of std::condition_variable_any but that requires a mutex of sorts which is yet again unnessesary in my case.
You need a lock to prevent this common newbie mistake:
Producer thread produces something,
Producer thread calls some_condition.notify_all(),
Producer thread goes idle for a while,
meanwhile:
Consumer thread calls some_condition.wait(...)
Consumer thread waits,...
And waits,...
And waits.
A condition variable is not a flag. It does not remember that it was notified. If the producer calls notify_one() or notify_all() before the consumer has entered the wait() call, then the notification is "lost."
In order to prevent lost notifications, there must be some shared data that tells the consumer whether or not it needs to wait, and there must be a lock to protect the shared data.
The producer should:
Lock the lock,
update the shared data,
notify the condition variable,
release the lock
The consumer must then:
Lock the lock,
Check the shared data to see if it needs wait,
Wait if needed,
consume whatever,
release the lock.
The consumer needs to pass the lock in to the wait(...) call so that wait(...) can temporarily unlock it, and then re-lock it before returning. If wait(...) did not unlock the lock, then the producer would never be able to reach the notify() call.
I am confused on one point with notify method. "notify() : It wakes up one single thread that called wait() on the same object." So lets say two thread called wait for the same object. So when I call notify which thread will be notified?
You can't know which one will be notified. Spec says:
public final void notify()
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation.
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.
pthread_cond_broadcast is used to wake up several threads waiting on a condition variable. But, at the same time it is also said that we should place a mutex before the condition variable to avoid race conditions.
So, if a mutex is there, and one thread already holds it and thus waits on the variable, how can any other thread hold the same mutex (to enter to the waiting part)?
When a thread calls pthread_cond_wait() it needs to hold the associated mutex. The API will release the mutex while it blocks the thread. Once the API decides the thread needs to be released, it will acquire the mutex before returning from the API.
Holding the mutex is required because checking the condition then calling pthread_cond_wait() isn't an atomic operation. The mutex (and the proper use of the mutex) prevents the thread from missing the condition becoming true in the short period between checking it and calling the wait.
But the short answer to the specific question (how can another thread obtain the mutex) is that while the thread is blocked in pthread_cond_wait(), the mutex is not held.
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();