asio::io_service将立即结束工作



我正在尝试学习io_service并使用共享指针。我希望代码能无限工作,直到我调用stop方法或类似的东西。不幸的是,在屏幕上看到workHandler的输出后,程序关闭了。有人能解释为什么会发生这种事吗?

#include <boost/asio.hpp>
#include <iostream>
#include <atomic>
#include <memory>
#include <thread>
#include <vector>
class Service : public std::enable_shared_from_this<Service> {
std::shared_ptr<boost::asio::io_service> _service;
std::shared_ptr<boost::asio::io_service::work> _work;
std::vector<std::thread> _threads;
std::atomic<bool> _started{false};
public:
Service() 
: _service(std::make_shared<boost::asio::io_service>()),
_work(std::make_shared<boost::asio::io_service::work>(*_service))
{}
void start() { 
auto self(this->shared_from_this());
auto startHandler = [this, self]() {
std::cout << "StartHandlern";
while(!_started) _service->run();
};
_threads.emplace_back(std::thread(startHandler));
}
std::shared_ptr<boost::asio::io_service>& get() { return _service; }
};
class Worker : public std::enable_shared_from_this<Worker> {
std::shared_ptr<Service> _service;
std::shared_ptr<boost::asio::io_service> _io_service;
public:
Worker(const std::shared_ptr<Service>& service)
: _service(service),
_io_service(_service->get())
{}
void work() {
auto self(this->shared_from_this());
auto workHandler = [this, self]() {
std::cout << "WorkHandlern";
};
_io_service->post(workHandler);
}
};
int main() {
auto ser = std::make_shared<Service>();
ser->start();
auto worker = std::make_shared<Worker>(ser);
worker->work();
}

您遇到了未定义的行为。

您的处理程序可以捕获指向Service/Work对象的共享指针。但没有什么能阻止main退出,它将运行退出处理程序并拆除全局库基础设施。这不是你想要的。

这些问题是由过度使用共享指针引起的。共享指针只适用于共享所有权。在大多数代码中,没有共享所有权(main拥有服务!(。简化:

在Coliru上直播

#include <boost/asio.hpp>
#include <boost/optional.hpp>
#include <iostream>
#include <memory>
#include <thread>
#include <list>
namespace ba = boost::asio;
class Service {
ba::io_service _service;
boost::optional<ba::io_service::work> _work {_service};
std::list<std::thread> _threads;
public:
~Service() {
_work.reset(); // allow service to complete
for (auto& thread : _threads)
if (thread.joinable())
thread.join();
}
void start() { 
_threads.emplace_back([this] {
_service.run();
});
}
ba::io_service& get() { return _service; } 
};
class Worker : public std::enable_shared_from_this<Worker> {
ba::io_service& _io;
public:
Worker(Service& service) : _io(service.get()) {}
void work() {
auto self(shared_from_this());
auto workHandler = [self]() {
std::cout << "WorkHandler " << std::endl;
};
_io.post(workHandler);
}
};
int main() {
Service ser;
ser.start();
std::make_shared<Worker>(ser)->work();
}

打印

WorkHandler

但最重要的是:不调用UB,而是通过连接线程干净地退出。

最新更新