
On 4/18/07, Ken <krovchuck@gmail.com> wrote:
On Apr 13, 2007, PJ Durai wrote:
I have two threads waiting on a condition. When I call condition::notify_all() from the main thread, I expected both threads to fall through and proceed simultaneously.
But that is not what I am witnessing. They behave like I had called condition::notify_one() twice.
One thread continues, does its thing (in this case a simple Sleep and a printf) comes back to wait. Only after that point the second thread continued from the condition.
Is this expected ? What am I missing ?
Its possible. notify_all() will make the threads ready to run, its up to the OS as to when they actually run. So if the Sleep is short enough, what you observe could happen. On a win32 platform, though, I would expect the second thread to wake when the first encounters the Sleep().
I can post the code if anyone wants to take a look.
Yes, this would help.
Ken Krovchuck
Thanks Ken. Here is the reproducing piece of code. This is compilable. Just paste it into a cpp file and compile in a MSVC 2005 command prompt. Here is the compilation command I used.. ====== build.bat ====== cl threadtest1.cpp /I "C:\Boost\include\boost-1_33_1" /D _CRT_SECURE_NO_DEPRECATE /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /EHsc /W3 /nologo /MDd /link /LIBPATH:"c:\Boost\lib" Please run threadtest1.exe and hit 'g' to observe the behaviour. ======== output (they are firing one after another..) ======== C:\home\pjdurai\dev\boosttest>threadtest1 thread0 : waiting ... thread1 : waiting ... thread0 : before cond wait... thread1 : before cond wait... thread1 : after cond wait... thread1 : doing stuff... 1111111111 thread1 : waiting ... thread0 : after cond wait... thread1 : before cond wait... thread0 : doing stuff... 0000000000 thread0 : waiting ... thread0 : before cond wait... =========== threadtest1.cpp =========== #include <stdio.h> #include <tchar.h> #include <windows.h> #include <conio.h> #include <string> #include <vector> #include <functional> #include <iostream> #include <boost/thread/thread.hpp> #include <boost/thread/xtime.hpp> #include <boost/thread/condition.hpp> #include <boost/thread/barrier.hpp> #define NUM_THREADS 2 boost::mutex io_mutex; boost::mutex mutex; boost::condition cond; void MyTrace(const char* format, ...) { char buf[256]; va_list marker; va_start(marker, format); vsprintf(buf, format, marker); { boost::mutex::scoped_lock lock(io_mutex); printf("%s\n", buf); OutputDebugStringA(buf); } va_end(marker); } #define TRACE MyTrace class Poll { public: Poll(std::string _name, int _id) : name(_name) { id = _id; } void operator() () { while(1) { { TRACE("%s : waiting ...\n", name.c_str()); { TRACE("%s : before cond wait...\n", name.c_str()); boost::mutex::scoped_lock lk(mutex); cond.wait(lk); TRACE("%s : after cond wait...\n", name.c_str()); { TRACE("%s : doing stuff...\n", name.c_str()); Sleep(4000); for (int i=0; i<10; ++i) std::cout << id; std::cout << std::endl; } } } //barrier.wait(); } } private: std::string name; int id; }; void ThreadTest() { boost::thread_group threads; for(int i=0; i<NUM_THREADS; ++i) { char buf[16]; sprintf(buf, "%d", i); std::string name = "thread"; name += buf; boost::thread* thrd = new boost::thread( Poll(name, i) ); threads.add_thread(thrd); } while( 1) { if (!_kbhit() ) Sleep(100); else { int c = _getch(); switch(c) { case 'q': return; case 'g': cond.notify_all(); break; case 'o': cond.notify_one(); break; } } } } void main(int argc, char** argv) { ThreadTest(); } ====================================== Please tell me if I can to do anything else to help.