Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Boost thread sleep deadlock

I have a problem with the following code:

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

void f1(uint count)
{
  while(count-- > 0)
  {
//    boost::this_thread::sleep(boost::posix_time::millisec(1000));
    sleep(1);
  }
}

void folkflore()
{
  int res = fork();
  //parent
  if ( res )
   {
     wait(NULL);
   }
  else
   {
     unsigned int x = 2;
     boost::thread tx(boost::bind(f1, 2));
     tx.join();
     _exit(-5);
   }
}

int main()
{
   std::cout << "Main program " << getpid() << std::endl;
   unsigned int x = 2;
   boost::thread t1(boost::bind(f1, 2));

   boost::thread m(folkflore);
   m.join();
   t1.join();
   return 0;
}

[LATER EDIT] Ok, so it looks like boost::this_thread::sleep acquires a mutex in the behind-scenes, so I guess I'll stick with plain old sleep() which is plain old good for me. [/LATER EDIT]

From main() I issue a t1 thread which counts 2 seconds and another thread which does the following: fork()'s inside it, the parent waits for the child and the child creates another thread which also counts 2 seconds.

The problem is that if I use boost::this_thread:sleep the program hangs or deadlocks somehow. If I use sleep(), then it works ok. Am I doing something wrong here? What is the difference between these two ?

From the man-page of sleep I get that:

"sleep() makes the calling thread sleep until seconds seconds have elapsed or a signal arrives which is not ignored. "

Also from the boost docs, boost::this_thread::sleep seems to do the same thing.

like image 937
FlorinP Avatar asked Nov 15 '11 11:11

FlorinP


1 Answers

You do dangerous things here: fork call duplicates the whole program, but only one thread (current one) running in new process. So all mutex here, but only one thread. And if some thread lock mutexes and your thread try lock it in new process, it will wait forever.

Here

boost::this_thread::sleep(boost::posix_time::millisec(1000));

if look at boost's include file, sleep looks like:

this_thread::sleep(get_system_time()+rel_time);

get_system_time call tz_convert from libc, which take mutex. And looks like before fork another thread lock it, and...

like image 179
fghj Avatar answered Oct 01 '22 21:10

fghj