When using tbb's thread engine, would the tbb thread (worker) becomes idle when reaching a location of trying to lock the mutex and become blocked? Would tbb instead switch the thread (worker) to execute other tasks?
In other words, if I have 4 tbb threads (workers), all are fighting for a mutex. Then before the use of mutex ends, effectively, only one thread is in execution. The others are all waiting (idling), even if there are other tasks to be spawned? Is this the correct understanding?
yes, by default they are fighting for the lock.
maybe try_lock can help here. http://en.cppreference.com/w/cpp/thread/mutex/try_lock. tbb::mutex supports std:mutex interfaces.
@Vladirmir, thanks for your comment, but this is not what I intended to ask for.
What I want to know is, when a tbb thread (worker) is waiting for the lock on a mutex, would tbb engine recognizes the worker is idling and switch the worker to execute other tasks?
I am asking this question at the level of TBB thread engine implementation. I also understand the logical thread and cpu core execution are different notions. For example, in other multi-threading engines, such as boost::thread and std::thread, they reply on the OS to context switch thread execution. If one thread is blocked (by waiting for mutex), another thread may be switched in for execution.
TBB is quite different in the sense that it has a fixed number of thread workers, each correspond to one cpu core by default. Thus, assuming no extra threads are created, when a worked thread is blocked, OS can't really do any context switching as there are no extra threads. Thus, I wonder if there is any mechanism in TBB that recognize such idling window and use the worker thread to steal and execute a different task.
Spin mutex apparently is out of the question as the cpu is busy trying to obtain the lock. But for mutex such as queue_mutex, I would imagine the thread is actually blocked and waits for a signal from the OS to re-try obtaining the mutex. There may be an opportunity for stealing here. This is what I want to ask, whether TBB simply let the worker to idle or not.
TBB does not support/provide the mechanism that you have described. So the worker wastes cpu time when waiting for the lock on a mutex.
Is your question a theoretical one or do you have a real problem? I am asking because TBB provides many other mechanisms to avoid/reduce wasting time while trying to acquire a lock. Perhaps, another solution exists.
The question is mostly theoretical. I need to know this answer so that I can choose from one of the two different designs for a critical component, both of which involves tbb. One of them has mutex and the other has none. But the second one is harder to write and debug. So, I have been scratching my head trying to be smart....
Thanks for your answer. I will go with Design #2.
Maybe there could be a new building block that combines the idea of an aggregator with the earlier and central idea of a dependency, for use where a critical section takes too much time to use an aggregator (which minimises overhead but still blocks the executing thread while waiting for the result). If you can enqueue your work as a task on an ad-hoc queue with the same scope as the mutex would have, and then wait for it to finish, you have just translated what you want into a language that TBB understands, and the scheduler will then oblige by doing exactly what you want, including keeping the thread busy by stealing any available other work. There are enough distracting details here that it should be useful to formalise it into something that can be optimised once and then reused.