Как узнать, когда завершился асинхронный конечный автомат. (Повышение :: Statechart)

Мне нужно создать boost :: statechart :: asynchronous_state_machine, и мне нужно иметь возможность «уничтожить» его внешне.
Я нашел в документах, что я должен вызвать destroy_processor и прекратить это делать. Проблема заключается в том, что эти методы просто вставляют событие в очередь событий компьютера, и поэтому, если я удаляю fifo_scheduler<> перед обработкой этих событий возникает ошибка … (см. пример ниже)

Вопрос в том … Как я могу узнать, когда asynchronous_state_machine «завершен» и безопасно «удалить» fifo_scheduler<>?

#include <boost/statechart/event.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/custom_reaction.hpp>

#include <boost/statechart/asynchronous_state_machine.hpp>
#include <boost/statechart/fifo_scheduler.hpp>#include <boost/intrusive_ptr.hpp>

#include <boost/asio/io_service.hpp>
#include <boost/thread/thread.hpp>#include <iostream>namespace sc = boost::statechart;
// States
struct Stop;
struct Running;
struct Playing;
struct Paused;

// Events
struct EvPlay : public sc::event<EvPlay>{};
struct EvStop : public sc::event<EvStop>{};
struct EvPause : public sc::event<EvPause>{};

// State machine and states definition
struct MyMachine : public sc::asynchronous_state_machine<MyMachine,Stop>
{
public:
MyMachine (my_context ctx, const unsigned int& ai_id)
: my_base(ctx)
, m_id(ai_id)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "MyMachine["<< m_id << "]: Constructor  "<< std::endl;
}

~MyMachine (void)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "MyMachine["<< m_id << "]: Destructor  "<< std::endl;
}

unsigned int id(void)const
{
return m_id;
}

private:
unsigned int m_id;
};struct Stop : sc::state<Stop,MyMachine>
{
public:

typedef sc::custom_reaction<EvPlay> reactions;

Stop(my_context ctx)
: my_base(ctx)
, m_id(context<MyMachine>().id())
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnEntry["<< m_id << "]: Stop  "<< std::endl;
}
~Stop(void)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnExit["<< m_id << "]: Stop  "<< std::endl;
}

sc::result react(const EvPlay&)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "Stop::Event["<< m_id << "]: EvPlay  "<< std::endl;
return transit<Running>();
}

private:
unsigned int m_id;
};

struct Running : sc::state <Running, MyMachine, Playing>
{
public:

typedef sc::custom_reaction<EvStop> reactions;

Running(my_context ctx)
: my_base(ctx)
, m_id(context<MyMachine>().id())
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnEntry["<< m_id << "]: Running  "<< std::endl;
}

~Running(void)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnExit["<< m_id << "]: Running  "<< std::endl;
}

sc::result react(const EvStop&)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "Running::Event["<< m_id << "]: EvStop  "<< std::endl;
return transit<Stop>();
}
private:
unsigned int m_id;
};

struct Playing : sc::state<Playing, Running>
{
public:

typedef sc::custom_reaction<EvPause> reactions;

Playing(my_context ctx)
: my_base(ctx)
, m_id(context<MyMachine>().id())
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnEntry["<< m_id << "]: Playing  "<< std::endl;
}

~Playing(void)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnExit["<< m_id << "]: Playing  "<< std::endl;
}

sc::result react(const EvPause&)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "Playing::Event["<< m_id << "]: EvPause  "<< std::endl;
return transit<Paused>();
}

private:
unsigned int m_id;
};

struct Paused : sc::state<Paused, Running>
{
public:

typedef sc::custom_reaction<EvPause> reactions;

Paused(my_context ctx)
: my_base(ctx)
, m_id(context<MyMachine>().id())
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnEntry["<< m_id << "]: Paused  "<< std::endl;
}

~Paused(void)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "OnExit["<< m_id << "]: Paused  "<< std::endl;
}

sc::result react(const EvPause&)
{
std::cout << "th["<< boost::this_thread::get_id()  << "]"<< "Paused::Event["<< m_id << "]: EvPause  "<< std::endl;
return transit<Playing>();
}

private:
unsigned int m_id;
};

// ---------------------------------------------------------------------------int main(void)
{

// create threadpool and ioservice
boost::thread_group threadPool;
boost::asio::io_service ioService;

// create work for ioservice
boost::asio::io_service::work* work (new boost::asio::io_service::work(ioService));

// create threads
threadPool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));// create machines
sc::fifo_scheduler<>* sch1(new sc::fifo_scheduler<>(true));
sc::fifo_scheduler<>::processor_handle handle1 (sch1->create_processor<MyMachine>(1));//initiate machines
sch1->initiate_processor(handle1);ioService.post(boost::bind(&sc::fifo_scheduler<>::operator(),sch1,0));boost::this_thread::sleep(boost::posix_time::milliseconds(1000));

std::cout << "main_th["<< boost::this_thread::get_id()  << "]:" << "destroying ... " << std::endl;
sch1->destroy_processor(handle1);
sch1->terminate();
std::cout << "main_th["<< boost::this_thread::get_id()  << "]:" << " ... destroyed " << std::endl;

// some time to process the events ( not a solution ) ...
// comment this line to get the error.
boost::this_thread::sleep(boost::posix_time::milliseconds(5000));

std::cout << "main_th["<< boost::this_thread::get_id()  << "]:" << "deleting ... "<< std::endl;
delete sch1;
sch1 = 0;
std::cout << "main_th["<< boost::this_thread::get_id()  << "]:" << " ... deleted"<< std::endl;// kill work to exit
delete work;
work = 0;

//wait for all threads to exit
threadPool.join_all();

return 0;
}

2

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector