Boost.Fiber纤程需显式join/detach,用boost::fibers::mutex而非std::mutex,sleep_for需启用调度器,IO/同步调用须异步化或外包至OS线程。

boost::fiber 怎么启动一个纤程
直接用 boost::fiber 构造函数或 boost::fibers::async 启动,但别忘了它默认不自动 join —— 启动后主线程退出,纤程可能被强制终止,连析构函数都不执行。
常见错误现象:std::terminate 或静默崩溃,尤其在纤程里用了 std::unique_ptr 或 RAII 资源;或者日志只打了一半就没了。
- 用
boost::fibers::fiber f{[](){ /* work */ }};后必须显式调用f.join()或f.detach() - 更安全的写法是
auto f = boost::fibers::async([](){ /* work */ }); f.get();,get()会阻塞并传播异常 - 如果纤程需长期运行(比如事件循环),确保有地方调用
boost::fibers::sleep_for()或boost::fibers::yield(),否则可能饿死其他纤程
纤程里怎么安全访问共享数据
不能直接套用线程那一套 std::mutex —— boost::fiber 是用户态调度,std::mutex 的系统调用会把整个线程(含其下所有纤程)挂起,严重降低并发效率。
使用场景:多个纤程轮询同一队列、更新计数器、读写配置缓存。
立即学习“C++免费学习笔记(深入)”;
- 优先用
boost::fibers::mutex替代std::mutex,它是纤程感知的,只挂起当前纤程,不阻塞底层 OS 线程 -
boost::fibers::condition_variable配合boost::fibers::mutex实现纤程间等待,别混用std::condition_variable - 对简单变量(如
int计数器),考虑std::atomic,它不依赖调度器,纤程/线程都安全
为什么 fiber::sleep_for 不生效或卡死
根本原因:没启用 fiber-aware 的时钟调度器。默认情况下 boost::fibers::sleep_for 依赖底层定时器,而 Boost.Fiber 需要你主动安装调度器(scheduler)才能正确处理超时。
错误现象:调用 sleep_for(1s) 后立刻返回,或永远不返回,甚至导致整个程序无响应。
- 确保在任何纤程启动前,已调用
boost::fibers::use_scheduling_algorithm<:fibers::algo::round_robin>();</:fibers::algo::round_robin> - 如果用了自定义调度器(比如带优先级的),确认它实现了
wait_until_()方法,否则sleep_for退化为忙等 - 注意时钟类型:用
std::chrono::steady_clock,别用system_clock,后者可能因系统时间调整导致异常偏移
从 thread 切换到 fiber 有哪些兼容性坑
Boost.Fiber 不是线程的轻量替代品,而是协作式调度模型——它要求所有“可能阻塞”的操作都显式让出控制权,否则一个纤程跑飞,其他全卡住。
典型踩坑点:把原有线程代码原样搬进纤程函数里,结果发现网络 IO、文件读写、第三方库回调全变成阻塞式,整个纤程调度器瘫痪。
- 标准库 IO(
std::cin、std::fstream)不能直接用,需换成异步版本(如boost::asio::streambuf+boost::fibers::asio::yield_token) - 第三方同步库(如某些数据库 client)大概率不兼容,要么找它的 async 接口,要么把它扔到
boost::fibers::async([]{ /* blocking call */ })包裹的独立 OS 线程里执行 -
new/delete没问题,但注意全局 new_handler 或 TLS 变量可能在线程和纤程间行为不一致,建议用boost::fibers::fiber_specific_ptr替代thread_local
最常被忽略的是调度器生命周期:如果 main 函数结束得太早,哪怕还有纤程在跑,boost::fibers::scheduler 实例已被销毁,后续 yield 或 sleep 就是未定义行为。







