|
Boost Users : |
From: PJ Durai (pjdtech2000_at_[hidden])
Date: 2007-04-19 12:50:48
On 4/18/07, Ken <krovchuck_at_[hidden]> 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.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net