I have a question related to std::condition_variable. I read a lot about it and all examples shown locked mutex before using std::condition_variable like that:
std::unique_lock<std::mutex> lock(mutex);
condition_variable.wait(lock);
//...
or like that:
std::unique_lock<std::mutex> lock(mutex);
condition_variable.notify_one();
//...
Is it necessery to lock mutex before using condition variable or is it thread-safe?
As mentioned in the comments, notify_one() doesn't need a locked mutex in order to be called, but wait(lock) does. condition_variable is somewhat unfortunately named because it gives the option to wait unconditionally for something to happen. A more useful version is wait(lock, condition), where the thread waits only if the condition is not true, otherwise it doesn't wait at all.
An analogy can be made with a hotel reception desk, where the condition_variable in a worker thread is a receptionist, the mutex represents a critical shared resource (say, a computer for making reservations), and the condition is the presence of patrons. Checking into a hotel involves a lot of steps, most of which can be done in parallel by different receptionists, but that one step of entering your details into the computer can't - receptionists have to use the computer one at a time.
Assume that the first thing that receptionists do when they get to work is check if the computer is free (no other receptionists are using it). In the case of wait(lock), receptionists will do that and then immediately fall asleep regardless of whether there are people waiting at the reception to be checked in. In the case of wait(lock, condition) they will fall asleep only if the condition is not true (there are no people waiting).
Now, if a receptionist is asleep, they are not going to notice when there are people at the desk waiting to be checked in. That's what notify_one() does - wakes up a receptionist. The action of waking up a receptionist does not depend on the state of the computer (the mutex) - you can keep ringing the bell at the reception desk even if all the receptionists are awake and checking people in like crazy (think a 4-year-old left without supervision who finds the bell...). notify_one() wakes up one receptionist, whereas notify_all() wakes up all of them.
The analogy is not perfect, but it illustrates the dependence between a condition_variable and a locked mutex.
Related
Threads and parallel programming is really confusing the heck outta me. In this book, at page 9, the problem stated is that though a thread might be scheduled and put in the ready state, it does not necessarily mean that it has acquird a lock.
Briefly put, a thread (say t1) waiting on a lock is notified via a condition_variable and the thread is put in the ready state, but not executed. But just before it can run anything, another thread is scheduled (say t2) and executed. This means that the condition under which t1 assumes it is woken up no longer holds.
Does this imply that merely scheduling a thread or putting it the ready state does not mean that it acquired a lock? If this is the case, must I always put the precondition in a while loop? Is this another possible meaning of a spurious wakeup? Also, what other cases like this must I be aware of?
I was always under the assumption that if a thread is woken up from a wait (which is not a spurious wakeup), it immediately acquires the lock (wakeup = lock acquired, under this circumstance), as the kernel keeps track of this.
This question is in close relation to my other question posted here.
Thanks.
Where can I ask these noob questions, in sort of an interactive format with follow-up questions? These seem too dumb for stackoverflow.
must I always put the condition in a while loop?
It's good practice to do so. Even if you know that on some particular hardware platform and OS, it's impossible for the wait() to return unless the condition is true; it could behave differently after the OS has been updated, or it could behave differently if your code gets moved to a different platform, or it could behave differently after some change is made to your code.
If you ever work developing "enterprise" software, then changes like that can and will happen. Might as well start learning good habits that can help to avert future disasters.
I was always under the assumption that if a thread is woken up from a wait (which is not a spurious wakeup), it immediately acquires the lock
You can safely assume that wait() will not, under any circumstances, ever return until the mutex has been re-locked. The whole wait()/notify() paradigm depends on it behaving in that way.
Given a situation where thread A had to dispatch work to thread B, is there any synchronisation mechanism that allows thread A to not return, but remain usable for other tasks, until thread B is done, of which then thread A can return?
This is not language specific, but simple c language would be a great choice in responding to this.
This could be absolutely counterintuitive; it actually sounds as such, but I have to ask before presuming...
Please Note This is a made up hypothetical situation that I'm interested in. I am not looking for a solution to an existing problem, so alternative concurrency solutions are completely pointless. I have no code for it, and if I were in it I can think of a few alternative code engineering solutions to avoid this setup. I just wish to know if a thread can be usable, in some way, while waiting for a signal from another thread, and what synchronisation mechanism to use for that.
UPDATE
As I mentioned above, I know how to synchronise threads etc. Im only interested in the situation that I have presented here. Mutexes, semaphores and locks all kinds of mechanisms will all synchronise access to resources, synchronise order of events, synchronise all kinds of concurrently issues, yes. But Im not interested in how to do it properly. I just have this made up situation that I wish to know if it can be addressed with a mechanism as described prior.
UPDATE 2
It seems I have opened up a portal for people that think they are experts in concurrency to teleport and lecture at chance how they think the rest of world does not know how threading works. I simply asked if there is a mechanism for this situation, not a work around solution, not 'the proper way to synchronise', not a better way to do it. I already know what I would do and never be in this made up situation. It's simply hypothetical.
After much research, thought, and overview, I have come to the conclusion that its like asking:
If a calculator has the ability for me simply enter a series of 5 digits and automatically get their sum on the screen.
No, it does not have such a mode ready. But I can still get the sum with a few extra clicks using the plus and eventually the equal button.
If i really wanted a thread that can continue while listening for a condition of some sort, I could easily implement a personal class or object around the OS/kernel/SDK thread or whatever and make use of that.
• So at a low level, my answer is no, there is no such mechanism •
If a thread is waiting, then it's waiting. If it can continue executing then it is not really 'waiting', in the concurrency meaning of waiting. Otherwise there would be some other term for this state (Alert Waiting, anyone?). This is not to say it is not possible, just not with one simple low level predefined mechanism similar to a mutex or semaphore etc. One could wrap the required functionality in some class or object etc.
Having said that, there are Interrupts and Interrupt handlers, which come close to addressing this situation. However, an interrupt has to be defined, with its handler. The interrupts may actually be running on another thread (not to say a thread per interrupt). So a number of objects are involved here.
You have a misunderstanding about how mutexes are typically used.
If you want to do some work, you acquire the mutex to figure out what work you need to do. You do this because "what work you need to do" is shared between the thread that decide what work needed to be done and the thread that's going to do the work. But then you release the mutex that protects "what work you need to do" while you do the work.
Then, when you finish the work, you acquire the mutex that protects your report that the work is done. This is needed because the status of the work is shared with other threads. You set that status to "done" and then you release the mutex.
Notice that no thread holds the mutex for very long, just for the microscopic fraction of a second it needs to check on or modify shared state. So to see if work is done, you can acquire the mutex that protects the reporting of the status of that work, check the status, and then release the mutex. The thread doing the work will not hold that mutex for longer than the tiny fraction of a second it needs to change that status.
If you're holding mutexes so long that you worry at all about waiting for them to be released, you're either doing something wrong or using mutexes in a very atypical way.
So use a mutex to protect the status of the work. If you need to wait for work to be done, also use a condition variable. Only hold that mutex while changing, or checking, the status of the work.
But, If a thread attempts to acquire an already acquired mutex, that thread will be forced to wait until the thread that originally acquired the mutex releases it. So, while that thread is waiting, can it actually be usable. This is where my question is.
If you consider any case where one thread might slow another thread down to be "waiting", then you can never avoid waiting. All that has to happen is one thread accesses memory and that might slow another thread down. So what do you do, never access memory?
When we talk about one thread "waiting" for another, what we mean is waiting for the thread to do actual work. We don't worry about the microscopic overhead of inter-thread synchronization both because there's nothing we can do about it and because it's negligible.
If you literally want to find some way that one thread can never, ever slow another thread down, you'll have to re-design pretty much everything we use threads for.
Update:
For example, consider some code that has a mutex and a boolean. The boolean indicates whether or not the work is done. The "assign work" flow looks like this:
Create a work object with a mutex and a boolean. Set the boolean to false.
Dispatch a thread to work on that object.
The "do work" flow looks like this:
Do work. (The mutex is not held here.)
Acquire mutex.
Set boolean to true.
Release mutex.
The "is work done" flow looks like this:
Acquire mutex.
Copy boolean.
Release mutex.
Look at copied value.
This allows one thread to do work and another thread to check if the work is done any time it wants to while doing other things. The only case where one thread waits for the other is the one-in-a-million case where a thread that needs to check if the work is done happens to check right at the instant that the work has just finished. Even in that case, it will typically block for less than a microsecond as the thread that holds the mutex only needs to set one boolean and release the mutex. And if even that bothers you, most mutexes have a non-blocking "try to lock" function (which you would use in the "check if work is done" flow so that the checking thread never blocks).
And this is the normal way mutexes are used. Actual contention is the exception, not the rule.
From Programming Language Pragmatics, by Scott
synchronization can be implemented either by spinning (also called
busy-waiting) or by blocking.
In busy-wait synchronization, a thread runs a loop in which it keeps
reevaluating some condition until that condition becomes true (e.g.,
until a message queue becomes nonempty or a shared variable attains a
particular value)—presumably as a result of action in some other
thread, running on some other core.
In blocking synchronization (also called scheduler-based synchronization), the
waiting thread voluntarily relinquishes its core to some other thread. Before doing so, it leaves a note in some data structure associated with the synchronization
condition. A thread that makes the condition true at some point in the future will
find the note and take action to make the blocked thread run again.
Why is this synchronization mechanism called "blocking"?
Who blocks who?
Thanks.
Why is [it] called "blocking"?
Think of yourself driving to Grandma's house for thanksgiving dinner, when you come upon an accident scene: Tow truck operators are hooking up a big truck that's laying on its side, across the entire road. The traffic reporter on the radio says, "it's blocking both lanes." You might say that your way is blocked by the accident.
Who blocks who?
Like the text that you quoted says, It's voluntary. When you come upon the accident scene, you could just turn around and find a different way, but depending on how long the detour is, and on how soon it looks like they'll have the truck off to the side of the road, you might volunteer to sit and wait.
Software usually sits and waits. It's easier to write software that just waits, and its easier to to read and understand it. The kind of software that does not sit and wait is called a wait free algorithm, and they can be very tricky to write.
The Busy-waiting causes multiple unnecessary context switches as a process/thread repeatedly attempts to enter the critical section in a loop, so it costs much CPU time.
Blocking synchronization avoid this problem by having a process/thread block. It will be put into a waiting queue,instead of attempting to gain CPU time, the process/thread simply waits idly. No CPU cycles are wasted by a blocked process/thread, so other processes/threads can continue without unnecessarily sharing cycles. Once a critical section has been released by some other process/thread, something will wakeup the blocked process/thread.
So this is why this synchronization mechanism called blocking, it will be blocked or can not get cpu again util the lock is released by others.
Who blocks it? I would say the mechanism does it. It put the thread/process which not get the lock into a queue to wait and there is something like monitor to monitor the lock, once the lock is released, it will retrieve one from blocked queue.
This is really a question confusing me for a long time. I tried googling a lot but still don't quite understand. My question is like this:
for system calls such as epoll(), mutex and semaphore, they have one thing in common: as soon as something happens(taking mutex for example, a thread release the lock), then a thread get woken up(the thread who are waiting for the lock can be woken up).
I'm wondering how is this mechanism(an event in one thread happens, then another thread is notified about this) implemented on earth behind the scene? I can only come up with 2 ways:
Hardware level interrupt: For example, as soon as another thread releases the lock, an edge trigger will happen.
Busy waiting: busy waiting in very low level. for example, as soon as another thread releases the lock, it will change a bit from 0 to 1 so that threads who are waiting for the lock can check this bit.
I'm not sure which of my guess, if any, is correct. I guess reading linux source code can help here. But it's sort of hard to a noob like me. It will be great to have a general idea here plus some pseudo code.
Linux kernel has a built-in object class called "wait queue" (other OSes have similar mechanisms). Wait queues are created for all types of "waitable" resources, so there are quite a few of them around the kernel. When thread detects that it must wait for a resource, it joins the relevant wait queue. The process goes roughly as following:
Thread adds its control structure to the linked list associated with the desired wait queue.
Thread calls scheduler, which marks the calling thread as sleeping, removes it from "ready to run" list and stashes its context away from the CPU. The scheduler is then free to select any other thread context to load onto the CPU instead.
When the resource becomes available, another thread (be it a user/kernel thread or a task scheduled by an interrupt handler - those usually piggy back on special "work queue" threads) invokes a "wake up" call on the relevant wait queue. "Wake up" means, that scheduler shall remove one or more thread control structures from the wait queue linked list and add all those threads to the "ready to run" list, which will enable them to be scheduled in due course.
A bit more technical overview is here:
http://www.makelinux.net/ldd3/chp-6-sect-2
I've been reading up on multithreading and shared resources access and one of the many (for me) new concepts is the mutex lock. What I can't seem to find out is what is actually happening to the thread that finds a "critical section" is locked. It says in many places that the thread gets "blocked", but what does that mean? Is it suspended, and will it resume when the lock is lifted? Or will it try again in the next iteration of the "run loop"?
The reason I ask, is because I want to have system supplied events (mouse, keyboard, etc.), which (apparantly) are delivered on the main thread, to be handled in a very specific part in the run loop of my secondary thread. So whatever event is delivered, I queue in my own datastructure. Obviously, the datastructure needs a mutex lock because it's being modified by both threads. The missing puzzle-piece is: what happens when an event gets delivered in a function on the main thread, I want to queue it, but the queue is locked? Will the main thread be suspended, or will it just jump over the locked section and go out of scope (losing the event)?
Blocked means execution gets stuck there; generally, the thread is put to sleep by the system and yields the processor to another thread. When a thread is blocked trying to acquire a mutex, execution resumes when the mutex is released, though the thread might block again if another thread grabs the mutex before it can.
There is generally a try-lock operation that grab the mutex if possible, and if not, will return an error. But you are eventually going to have to move the current event into that queue. Also, if you delay moving the events to the thread where they are handled, the application will become unresponsive regardless.
A queue is actually one case where you can get away with not using a mutex. For example, Mac OS X (and possibly also iOS) provides the OSAtomicEnqueue() and OSAtomicDequeue() functions (see man atomic or <libkern/OSAtomic.h>) that exploit processor-specific atomic operations to avoid using a lock.
But, why not just process the events on the main thread as part of the main run loop?
The simplest way to think of it is that the blocked thread is put in a wait ("sleeping") state until the mutex is released by the thread holding it. At that point the operating system will "wake up" one of the threads waiting on the mutex and let it acquire it and continue. It's as if the OS simply puts the blocked thread on a shelf until it has the thing it needs to continue. Until the OS takes the thread off the shelf, it's not doing anything. The exact implementation -- which thread gets to go next, whether they all get woken up or they're queued -- will depend on your OS and what language/framework you are using.
Too late to answer but I may facilitate the understanding. I am talking more from implementation perspective rather than theoretical texts.
The word "blocking" is kind of technical homonym. People may use it for sleeping or mere waiting. The term has to be understood in context of usage.
Blocking means Waiting - Assume on an SMP system a thread B wants to acquire a spinlock held by some other thread A. One of the mechanisms is to disable preemption and keep spinning on the processor unless B gets it. Another mechanism probably, an efficient one, is to allow other threads to use processor, in case B does not gets it in easy attempts. Therefore we schedule out thread B (as preemption is enabled) and give processor to some other thread C. In this case thread B just waits in the scheduler's queue and comes back with its turn. Understand that B is not sleeping just waiting rather passively instead of busy-wait and burning processor cycles. On BSD and Solaris systems there are data-structures like turnstiles to implement this situation.
Blocking means Sleeping - If the thread B had instead made system call like read() waiting data from network socket, it cannot proceed until it gets it. Therefore, some texts casually use term blocking as "... blocked for I/O" or "... in blocking system call". Actually, thread B is rather sleeping. There are specific data-structures known as sleep queues - much like luxury waiting rooms on air-ports :-). The thread will be woken up when OS detects availability of data, much like an attendant of the waiting room.
Blocking means just that. It is blocked. It will not proceed until able. You don't say which language you're using, but most languages/libraries have lock objects where you can "attempt" to take the lock and then carry on and do something different depending on whether you succeeded or not.
But in, for example, Java synchronized blocks, your thread will stall until it is able to acquire the monitor (mutex, lock). The java.util.concurrent.locks.Lock interface describes lock objects which have more flexibility in terms of lock acquisition.