不,这不是问题。你不必担心的原因是“新股”是一个执行者。
Executors
可廉价复制并按价值传递。任何保留它的东西都会有它的副本。你可以把执行人想象成一个把手。当然,实现仍然存在于执行上下文中注册的相应服务中。
请注意,您在问题中比较的不同类型的线束
不同的
服务实现。坚持一种风格(当然是现代风格)会更有效率。
Simpler+Explicit:执行器,而不是上下文引用
我总是围绕执行者编写Asio代码:
Live On Coliru
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
using namespace std::chrono_literals;
namespace asio = boost::asio;
using Executor = asio::any_io_executor;
struct session : std::enable_shared_from_this<session> {
session(Executor context) : timer(make_strand(context)) {}
void start() {
co_spawn(timer.get_executor(), loop(shared_from_this()), asio::detached);
}
void stop() {
asio::post(timer.get_executor(), [me = shared_from_this()]() { me->timer.cancel(); });
}
private:
asio::steady_timer timer;
asio::awaitable<void> loop(std::shared_ptr<session> self) {
while (true) {
timer.expires_from_now(5s);
co_await timer.async_wait(asio::use_awaitable);
std::cout << "5 seconds expired" << std::endl;
self->stop();
}
}
};
int main() {
asio::thread_pool context;
{
auto s = make_shared<session>(context.get_executor());
s->start();
std::this_thread::sleep_for(7s);
s->stop();
}
context.join();
}
取消插槽?
当然,现在没有什么值得共享所有权了,所以你可以等效地写它的功能:
Live On Compiler Explorer
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
using namespace std::chrono_literals;
namespace asio = boost::asio;
using Executor = asio::thread_pool::executor_type; // also optimize avoiding type-erasure and allocations
using Action = asio::awaitable<void, Executor>;
Action do_session(asio::cancellation_slot sig) {
auto token = asio::bind_cancellation_slot(sig, asio::deferred);
asio::steady_timer timer{co_await asio::this_coro::executor};
while (true) {
timer.expires_from_now(5s);
co_await timer.async_wait(token);
std::cout << "5 seconds expired" << std::endl;
}
};
int main() {
asio::thread_pool context;
{
asio::cancellation_signal sig;
co_spawn(context.get_executor(), do_session(sig.slot()), asio::detached);
std::this_thread::sleep_for(7s);
sig.emit(asio::cancellation_type::terminal);
}
context.join();
}
静止打印