Opened 13 years ago
Closed 10 years ago
#3628 closed Bugs (invalid)
condition.notify_one() does not wake up a thread that is in condition.wait() or condition.timed_wait()
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | To Be Determined | Component: | thread |
Version: | Boost 1.40.0 | Severity: | Problem |
Keywords: | condition | Cc: |
Description
You can see in the attached project's TestBoostThread.cpp file that in ThreadFuncWaiter(), the thread is in timed_wait() call before it releases the mutex to let the ThreadFuncNotifier() thread notify it. But inside notify_one(), most of the time it will choose not to notify any "waiter". The total_count class member is 0 when that happens. If I uncomment the three lines marked as WORKAROUND_ in TestBoostThread.cpp, then the threads will be notified, but this is just a workaround.
Attachments (1)
Change History (11)
by , 13 years ago
Attachment: | TestBoostThread.zip added |
---|
comment:1 by , 13 years ago
follow-up: 3 comment:2 by , 13 years ago
Replying to Shouaib Ahmed <ranashoaib@…>:
You can see in the attached project's TestBoostThread.cpp file that in ThreadFuncWaiter(), the thread is in timed_wait() call before it releases the mutex to let the ThreadFuncNotifier() thread notify it. But inside notify_one(), most of the time it will choose not to notify any "waiter". The total_count class member is 0 when that happens. If I uncomment the three lines marked as WORKAROUND_ in TestBoostThread.cpp, then the threads will be notified, but this is just a workaround.
Have you tried to protect with a mutex the theConditions variable? This variable is used by ThreadFuncNotifier() and ThreadFuncWaiter().
follow-up: 4 comment:3 by , 13 years ago
Replying to viboes:
Replying to Shouaib Ahmed <ranashoaib@…>:
You can see in the attached project's TestBoostThread.cpp file that in ThreadFuncWaiter(), the thread is in timed_wait() call before it releases the mutex to let the ThreadFuncNotifier() thread notify it. But inside notify_one(), most of the time it will choose not to notify any "waiter". The total_count class member is 0 when that happens. If I uncomment the three lines marked as WORKAROUND_ in TestBoostThread.cpp, then the threads will be notified, but this is just a workaround.
Have you tried to protect with a mutex the theConditions variable? This variable is used by ThreadFuncNotifier() and ThreadFuncWaiter().
It is protected by a mutex. May be you overlooked that.
comment:4 by , 13 years ago
Replying to Shouaib Ahmed <ranashoaib@…>:
Replying to viboes:
Replying to Shouaib Ahmed <ranashoaib@…>:
You can see in the attached project's TestBoostThread.cpp file that in ThreadFuncWaiter(), the thread is in timed_wait() call before it releases the mutex to let the ThreadFuncNotifier() thread notify it. But inside notify_one(), most of the time it will choose not to notify any "waiter". The total_count class member is 0 when that happens. If I uncomment the three lines marked as WORKAROUND_ in TestBoostThread.cpp, then the threads will be notified, but this is just a workaround.
Have you tried to protect with a mutex the theConditions variable? This variable is used by ThreadFuncNotifier() and ThreadFuncWaiter().
It is protected by a mutex. May be you overlooked that.
You are right, I overlooked this mutex.
To which total_count class member are you referring to?
The explanation I found is that if you don't add the workaround, the thread ThreadFuncNotifier will lock the mutex during the iteration through the theConditions container + 500 (miliseconds?). This left enough time to make the wait for 50 milliseconds to expire. IMO you should not protect the Sleep neither in the thread ThreadFuncNotifier nor ThreadFuncWaiter.
The WORKAROUND_ Sleep(50); seems no necessary to me. Does it works without? HTH.
comment:6 by , 11 years ago
Milestone: | Boost 1.41.0 → To Be Determined |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:8 by , 10 years ago
With
unsigned int i = 0; for (Conditions::iterator it = theConditions.begin(); it != theConditions.end() && i < 2; ++it) { (*it)->notify_one(); //WORKAROUND_ lockMtx.unlock(); //WORKAROUND_ Sleep(50); cout << "Notified One " << theConditions.size() << endl; ++i; //WORKAROUND_ lockMtx.lock(); }
only the two first conditions will be notified, so there will be up to 10 threads that will not be notified.
comment:9 by , 10 years ago
I think that I understand why it could occur that sometimes some threads are not notified.
Both threads have a lock on theMutex. The underlying OS could choose to schedule the ThreadFuncNotifier thread as many times as it wants. One of the threads ThreadFuncWaiter ends by timeout as the ThreadFuncNotifier is not signaling the specific condition.
Let me know if you don't agree with my analysis. I will close the ticket as there is no evidence there is an issue on the library.
comment:10 by , 10 years ago
Resolution: | → invalid |
---|---|
Status: | assigned → closed |
Just wanted to mention that I am using Visual Studio 2008 on Windows XP.
Replying to Shouaib Ahmed <ranashoaib@…>: