问题描述
我正在尝试学习io_service并使用共享指针.我希望代码可以无限工作,直到我调用stop方法或类似的东西为止.不幸的是,在屏幕上看到workHandler的输出后,程序关闭了.谁能解释为什么会这样?
I'm trying to learn io_service and work with shared pointers. I want the code to work infinitely until I call stop method or sth like this. Unfortunately after seeing workHandler's output on the screen the program shutdowns. Can anybody explain why this happen?
#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 << "StartHandler\n";
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 << "WorkHandler\n";
};
_io_service->post(workHandler);
}
};
int main() {
auto ser = std::make_shared<Service>();
ser->start();
auto worker = std::make_shared<Worker>(ser);
worker->work();
}
推荐答案
您正在遇到不确定的行为.
You're running into undefined behaviour.
您的处理程序可以捕获指向Service/Work对象的共享指针.但是没有什么可以阻止 main
退出,这将运行退出处理程序并拆除全局库基础结构.这不是你想要的.
Your handlers capture shared pointers to the Service/Work objects alright. But nothing stops main
from exiting, which will run exit handlers and tear down global library infrastructure. This is not what you want.
问题是由过度使用共享指针引起的.共享指针仅对共享所有权有利.在您的大多数代码中,没有共享所有权( main
拥有服务!).简化:
The problems are caused by an over-use of shared pointers. Shared pointers are ONLY good for shared ownership. In the majority of your code there is no shared ownership (main
owns the Service!). Simplify:
Live On 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并通过加入线程来干净地退出.
But most importantly: doesn't invoke UB and exits cleanly through joining the threads.
这篇关于asio :: io_service立即结束工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!