我正在尝试学习 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 << "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();
}
您遇到了未定义的行为。
您的处理程序可以捕获指向服务/工作对象的共享指针。但什么都没有停止main
退出,这将运行退出处理程序并拆除全局库基础设施。这不是你想要的。
这些问题是由于过度使用共享指针引起的。共享指针仅适用于共享所有权。在您的大部分代码中,没有共享所有权(main
拥有该服务!)。简化:
住在科里鲁 http://coliru.stacked-crooked.com/a/83f6a7a50318c13f
#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();
}
Prints
WorkHandler
但最重要的是:不调用 UB 并通过加入线程干净地退出。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)