我的Boost.Asio线程池代码是否引发死锁?请求协助排查
问题排查:Boost.Asio thread_pool偶发挂起问题
我们在开发异步微服务时使用Boost.Asio的thread_pool类提升计算吞吐量,编写的测试代码偶发挂起,疑似死锁,代码如下:
#include <boost/asio/post.hpp> #include <boost/asio/thread_pool.hpp> #include <boost/asio/use_future.hpp> #include <cstdlib> #include <exception> #include <future> #include <iostream> #include <mutex> #include <thread> int main() { boost::asio::thread_pool pool{5}; std::mutex mutex; for(int i = 0; i < 5; ++i) { boost::asio::post(pool, [i, &mutex]() { try { std::lock_guard<std::mutex> lg{mutex}; std::cout << "Task " << i << " executed by thread " << std::this_thread::get_id() << std::endl; } catch(const std::exception& e) { std::cerr << e.what() << '\n'; } }); } std::future<int> r1 = boost::asio::post(pool, boost::asio::use_future([]() { return 2; })); { std::lock_guard<std::mutex> lg{mutex}; std::cout << "Result = " << r1.get() << '\n'; } // Optional: Wait for all tasks to complete pool.join(); return EXIT_SUCCESS; }
问题根源:循环等待导致死锁
代码的死锁场景触发条件如下:
- 主线程先通过
std::lock_guard获取了mutex,随后调用r1.get(),阻塞等待线程池中r1对应的任务执行完成并返回结果。 - 线程池初始化了5个线程,刚好被前5个任务占满。这5个任务都需要获取
mutex才能完成执行,但此时mutex被主线程持有,所以这5个线程都处于阻塞等待锁的状态。 r1对应的任务被放在线程池的任务队列中,没有空闲线程可以执行它。
此时形成循环等待的死锁:
- 主线程:持有
mutex→ 等待r1任务完成 - 线程池线程:等待
mutex→ 无法释放线程去执行r1任务
这种场景是偶发的,因为如果r1的任务在主线程获取锁之前就被线程池执行完成,就不会触发死锁;但如果前5个任务先抢占了所有线程,就会触发挂起。
修复方案
方案1:调整锁的持有时机(推荐)
先等待r1任务完成,再获取锁输出结果,避免主线程持有锁时等待线程池任务:
std::future<int> r1 = boost::asio::post(pool, boost::asio::use_future([]() { return 2; })); // 先等待任务完成,再获取锁输出 int result = r1.get(); { std::lock_guard<std::mutex> lg{mutex}; std::cout << "Result = " << result << '\n'; }
方案2:避免主线程与线程池任务竞争同一锁
如果主线程的输出操作不需要线程安全(仅测试场景),可以直接去掉主线程的锁:
std::future<int> r1 = boost::asio::post(pool, boost::asio::use_future([]() { return 2; })); std::cout << "Result = " << r1.get() << '\n';
方案3:增加线程池线程数(不推荐,仅降低概率)
将线程池线程数设为6,确保有空闲线程可以执行r1任务,但这只是降低死锁触发概率,无法从根本上解决问题。
内容的提问来源于stack exchange,提问作者anthonyNk
相关产品推荐
相关产品推荐

