Boost logo

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