找到解决方案
我正在使用 VS2013,boost 1.59.0
我有以下来自 boost c++ application development cookbook
的例子
我在 Windows 上停止 boost::ioservice
时遇到问题。我现在找到了一种解决方法来停止它,即使用 ios_.stopped()
。
#include <boost/thread/thread.hpp>
#include <boost/asio/io_service.hpp>
namespace detail
{
template <class T>
struct task_wrapped
{
private:
T task_unwrapped_;
public:
explicit task_wrapped(const T& task_unwrapped)
: task_unwrapped_(task_unwrapped)
{}
void operator()() const
{
// resetting interruption
try
{
boost::this_thread::interruption_point();
}
catch (const boost::thread_interrupted&){}
try
{
// Executing task
task_unwrapped_();
}
catch (const std::exception& e)
{
std::cerr << "Exception: " << e.what() << '\n';
}
catch (const boost::thread_interrupted&)
{
std::cerr << "Thread interrupted\n";
}
catch (...)
{
std::cerr << "Unknown exception\n";
}
}
};
template <class T>
task_wrapped<T> make_task_wrapped(const T& task_unwrapped)
{
return task_wrapped<T>(task_unwrapped);
}
} // namespace detail
class tasks_processor;
tasks_processor* pProcessor = nullptr;
class tasks_processor : private boost::noncopyable {
boost::asio::io_service ios_;
boost::asio::io_service::work work_;
tasks_processor()
: ios_()
, work_(ios_)
{}
public:
static tasks_processor& get()
{
if (pProcessor == nullptr)
{
pProcessor = new tasks_processor;
}
return *pProcessor;
}
template <class T>
inline void push_task(const T& task_unwrapped) {
ios_.post(detail::make_task_wrapped(task_unwrapped));
}
void start() {
ios_.run();
}
void stop() {
ios_.stop();
}
bool IsStopped() {
return ios_.stopped();
}
}; // tasks_processor
int g_val = 0;
void func_test()
{
if (tasks_processor::get().IsStopped())
return;
++g_val;
if (g_val == 3)
{
throw std::logic_error("Just checking");
}
boost::this_thread::interruption_point();
if (g_val == 10)
{
// Emulation of thread interruption.
// Will be caught and won't stop execution.
throw boost::thread_interrupted();
}
if (g_val == 90)
{
tasks_processor::get().stop();
}
}
int main()
{
static const std::size_t tasks_count = 100;
// stop() is called at 90
BOOST_STATIC_ASSERT(tasks_count > 90);
for (std::size_t i = 0; i < tasks_count; ++i)
{
tasks_processor::get().push_task(&func_test);
}
// We can also use result of boost::bind call
// as a task
tasks_processor::get().push_task(
boost::bind(std::plus<int>(), 2, 2) // counting 2 + 2
);
// Processing was not started.
assert(g_val == 0);
// Will not throw, but blocks till
// one of the tasks it is owning
// calls stop().
tasks_processor::get().start();
assert(g_val == 90);
return 0;
}
问题是变量 g_val
等于 100,这意味着 ios_.stop();
不工作。我以调试方式运行并且已调用此命令。如何停止 boost::ioservice
?
最佳答案
io_service::stop()
只是改变 io_service 事件循环的状态,它会导致 io_service::run()
调用尽快返回。没有记录 stop()
是否取消已经排队的处理程序,根据这个 post 看来它取决于操作系统.因此,当 g_val == 90
时,io_service::stop()
被调用,但剩余的 func_test()
可能仍会被执行。
关于c++ - 如何在 Windows 上停止 boost::ioservice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41905398/