使用asio::io_context::strand同步任务无输出,求正确实现方式
问题:使用Asio Strand同步任务无输出的解决方法
我尝试用strand同步完成处理程序,但未得到预期结果:不包装strand直接调用asio::post时,输出正常但任务不同步;用strand包装后完全没有输出。
最小可复现示例
#include <asio.hpp> #include <thread> #include <iostream> #include <vector> #include <random> struct Task { Task(int id, int wait_time) : id_{id} , wait_time_{wait_time} {} void operator()() { std::cout << "Tast-" << id_ << " started. [" << std::this_thread::get_id() << "]" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(wait_time_)); std::cout << "Task-" << id_ << " finished after (" << wait_time_ << ") milliseconds. [" << std::this_thread::get_id() << "]" << std::endl; } int id_; int wait_time_; }; int main() { std::random_device rd; std::mt19937 engine(rd()); std::uniform_int_distribution d(500, 2'000); asio::io_context ctx; asio::io_context::strand strand(ctx); std::vector<std::jthread> threads; auto count = 4; for (int i = 0; i < count; ++i) { threads.emplace_back([&]{ ctx.run(); }); } for (int i = 0; i < count * 2; ++i) { asio::post(Task(i + 1, d(engine))); // asio::post(strand.wrap(Task(i + 1, d(engine)))); /* THIS DOESN'T PRODUCE ANY OUTPUT */ } ctx.run(); }
无Strand时的输出
Tast-1 started. [17652] Tast-7 started. [26096] Tast-3 started. [56484] Tast-8 started. [32000] Tast-5 started. [Tast-6 started. [79448] 61340]Tast-2Tast-4 started. [55696] started. [84880] Task-6 finished after (784) milliseconds. [79448] Task-2 finished after (835) milliseconds. [84880] Task-1 finished after (923) milliseconds. [17652] Task-4 finished after (1281) milliseconds. [55696] Task-3 finished after (1668) milliseconds. [56484] Task-7 finished after (1763) milliseconds. [26096] Task-8 finished after (1888) milliseconds. [32000] Task-5 finished after (1982) milliseconds. [61340]
问题原因与修复方案
核心问题
你错误地使用了strand.wrap():将包装后的handler直接post到io_context,而非通过strand来投递任务。这种用法无法触发strand的串行调度逻辑,反而会导致任务无法被正确执行。
正确使用方式
有两种标准用法可以实现strand的同步效果:
- 直接通过strand的post方法投递任务(推荐,写法更简洁):
asio::post(strand, Task(i + 1, d(engine))); - 用strand.wrap()包装后,仍投递到strand:
asio::post(strand, strand.wrap(Task(i + 1, d(engine))));
修复后的完整代码
#include <asio.hpp> #include <thread> #include <iostream> #include <vector> #include <random> struct Task { Task(int id, int wait_time) : id_{id} , wait_time_{wait_time} {} void operator()() { std::cout << "Task-" << id_ << " started. [" << std::this_thread::get_id() << "]" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(wait_time_)); std::cout << "Task-" << id_ << " finished after (" << wait_time_ << ") milliseconds. [" << std::this_thread::get_id() << "]" << std::endl; } int id_; int wait_time_; }; int main() { std::random_device rd; std::mt19937 engine(rd()); std::uniform_int_distribution d(500, 2'000); asio::io_context ctx; asio::io_context::strand strand(ctx); std::vector<std::jthread> threads; auto count = 4; for (int i = 0; i < count; ++i) { threads.emplace_back([&]{ ctx.run(); }); } for (int i = 0; i < count * 2; ++i) { asio::post(strand, Task(i + 1, d(engine))); } ctx.run(); }
修复后效果
任务会严格串行执行,同一时间只有一个任务在运行,输出类似:
Task-1 started. [12345] Task-1 finished after (800) milliseconds. [12345] Task-2 started. [12345] Task-2 finished after (1200) milliseconds. [12345] ...
内容的提问来源于stack exchange,提问作者DailyLearner
相关产品推荐
相关产品推荐

