C ++ Boost поток сна тупик - PullRequest
       10

C ++ Boost поток сна тупик

6 голосов
/ 15 ноября 2011

У меня проблема со следующим кодом:

#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] Хорошо, похоже, boost :: this_thread :: sleep получает мьютекс в закулисных сценах, поэтому я думаю,Я буду придерживаться простого старого сна (), который хорошо для меня хорош.[/ LATER EDIT]

Из main () я выпускаю поток t1, который считает 2 секунды, и другой поток, который выполняет следующее: fork () внутри него, родитель ожидает дочернего элемента, а дочерний создаетдругой поток, который также считает 2 секунды.

Проблема в том, что если я использую boost :: this_thread: sleep, программа как-то зависает или блокируется.Если я использую sleep (), то все работает нормально.Я что-то здесь не так делаю?В чем разница между этими двумя?

Из man-страницы sleep я получаю следующее:

"sleep () заставляет вызывающий поток спать до тех пор, пока не пройдут секунды или не прибудет сигнал, которыйне игнорируется. "

Также из документов boost, boost :: this_thread :: sleep, кажется, делает то же самое.

1 Ответ

4 голосов
/ 15 ноября 2011

Вы делаете опасные вещи здесь: вызов fork дублирует всю программу, но работает только один поток (текущий) в новом процессе. Так что все мьютексы здесь, но только одна нить. И если какой-то поток блокирует мьютексы и ваш поток пытается заблокировать его в новом процессе, это будет ждать вечно.

Здесь

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

если посмотреть на включаемый файл boost, sleep выглядит так:

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

get_system_time вызывает tz_convert из libc, который принимает мьютекс. И выглядит, как перед тем, как разветвить другой поток, заблокировать его, и ...

...