Всем привет.
Начал потихоньку осваивать boost. Возникло несколько вопросов.
Имею примерно такой код
#include <boost/thread/thread.hpp>
class MSK {
public:
MSK();
protected:
static void RoutinePnP();
private:
boost::thread _pnpthread;
};
#include <iostream>
#include <boost/thread/xtime.hpp>
MSK::MSK()
{
_pnpthread = boost::thread(&RoutinePnP);
}
void MSK::RoutinePnP()
{
for(;;) {
std::cout << "PnP run..." << std::endl;
// приостанавливаем поток на 10 секунд
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += 10;
boost::thread::sleep(xt);
}
}
int main()
{
MSK msk;
std::cout << "message1" << std::endl;
std::cout << "message2" << std::endl;
std::cout << "message3" << std::endl;
std::cout << "message4" << std::endl;
while(1) sleep(1);
return EXIT_FAILURE;
}
Я бы рекомендовал для начала изучить неплохие примеры из Thread: C:\boost\boost_1_37_0\libs\thread\example\
На третий вопрос отвечу кодом из примера про голодных философов (starvephil.cpp):
class thread_adapter
{
public:
thread_adapter(void (*func)(void*), void* param)
: _func(func), _param(param)
{
}
void operator()() const { _func(_param); }
private:
void (*_func)(void*);
void* _param;
};
phil p[] = { phil(0), phil(1), phil(2), phil(3), phil(4) };
boost::thread thrd_phil0(thread_adapter(&phil::do_thread, &p[0]));
boost::thread thrd_phil1(thread_adapter(&phil::do_thread, &p[1]));
boost::thread thrd_phil2(thread_adapter(&phil::do_thread, &p[2]));
boost::thread thrd_phil3(thread_adapter(&phil::do_thread, &p[3]));
boost::thread thrd_phil4(thread_adapter(&phil::do_thread, &p[4]));
thrd_phil0.join();
thrd_phil1.join();
thrd_phil2.join();
thrd_phil3.join();
thrd_phil4.join();
#include <iostream>
#include <boost/thread/xtime.hpp>
#include <boost/thread/thread.hpp>
//для SetConsoleCtrlHandler ...
#include <windows.h>
class MSK {
public:
MSK() : is_running(false)
{
}
void run()
{
is_running = true;
while(is_running)
{
std::cout << "PnP run...\n";
// приостанавливаем поток на 10 секунд
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += 10;
boost::thread::sleep(xt);
}
std::cout << "[run] ok\n";
}
void stop()
{
is_running = false;
}
static void do_thread(void* param)
{
static_cast<MSK*>(param)->run();
}
private:
bool is_running;
};
class thread_adapter
{
public:
thread_adapter(void (*func)(void*), void* param)
: _func(func), _param(param)
{
}
void operator()() const { _func(_param); }
private:
void (*_func)(void*);
void* _param;
};
MSK msk;
BOOL WINAPI stop_handler(DWORD ctrl_type)
{
switch (ctrl_type)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_SHUTDOWN_EVENT:
std::cout << "waiting to stop...\n";
msk.stop();
return TRUE;
default:
return FALSE;
}
}
int main()
{
std::cout << "[start]\n";
boost::thread msk_thrd(thread_adapter(&MSK::do_thread, &msk));
SetConsoleCtrlHandler(&stop_handler, TRUE);
msk_thrd.join();
std::cout << "[stop]\n";
return 0;
}
#include <boost/thread/thread.hpp>
class MSK {
public:
MSK();
protected:
static void RoutinePnP();
private:
boost::thread _pnpthread;
};
#include <iostream>
#include <boost/thread/xtime.hpp>
MSK::MSK()
{
_pnpthread = boost::thread(&RoutinePnP);
}
void MSK::RoutinePnP()
{
for(;;) {
std::cout << "PnP run..." << std::endl;
// приостанавливаем поток на 10 секунд
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += 10;
boost::thread::sleep(xt);
}
}
int main()
{
MSK msk;
std::cout << "message1" << std::endl;
std::cout << "message2" << std::endl;
std::cout << "message3" << std::endl;
std::cout << "message4" << std::endl;
while(1) sleep(1);
return EXIT_FAILURE;
}
во-первых, в какой системе работаешь и какой компилятор?
далее, по пунктам:
1. это неноральное поведение, поток никак не может блокироаться в данном случае. 37-й буст - довольно старая версия. возможно, потоки были доработаны с тех пор. хотя я не сталкивалась с подобным глюком, но это может оказаться глюком библиотеки. возьми для начала новый буст.
также обязательно проверь, что компилишь проект с опциями мультипоточности (это важно, буст может работать неправильно, если эти опции не включены).
2. что значит "не привязываясь к системному времени? this_thread::sleep принимает и абсолютное, и относительное время. это перегруженная функция и можно скармливать ему и абсолютно время, и интервалы в формате posix_time::seconds, posix_time::microseconds, и т.д., в зависимости от возможностей твоей системы и макросов, которые ты указал для сборки.
3. создавай функтор с оператором operator() и передавай его. а в нём юзай что хочешь.
Iron Bug, спасибо за помощь, но тема достаточно устарела и ответы я давно получил )
а, не заметила даты. просто последний ответ был вчера. поэтому подумала, что тема новая. ну ладно, пусть будет.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)