众所周知,std::lock_guard 可能会出现死锁问题。我想知道处理这种情况的最佳做法是什么?
当使用std::lock_guard多处处理异常时,会引发死锁
我的代码
#include <boost/asio.hpp>
// // #include <boost/thread.hpp>
#include <boost/bind/bind.hpp>
#include <memory>
#include <mutex>
#include <iostream>
#include <thread>
#include <chrono>
std::mutex global_stream_lock;
void worker_thread(std::shared_ptr<boost::asio::io_service> iosvc, int i ){
{
std::lock_guard l {global_stream_lock};
std::cout<<"Thread"<<i<<"started"<<std::endl;
}
try{
std::lock_guard l {global_stream_lock};
iosvc->run();
std::cout<<"Thread "<<i<<"End \n";
}
catch(std::exception &ex){
{
std::cout << "Message: " << ex.what() << ".\n";
}
}
}
void throw_an_exception(std::shared_ptr<boost::asio::io_service> io_svc, int counter)
{
{
std::lock_guard l {global_stream_lock};
std::cout << "Throw Exception " << counter << "\n" ;
}
throw(std::runtime_error("The Exception !!!"));
}
int main(void) {
std::shared_ptr<boost::asio::io_service> io_svc (new boost::asio::io_service);
std::shared_ptr<boost::asio::io_service::work> worker (new boost::asio::io_service::work(*io_svc));
std::vector<std::jthread> threads;
{
std::lock_guard l {global_stream_lock};
std::cout << "The program will exit once all work has finished.\n";
}
boost::asio::io_service::strand strand(*io_svc);
//boost::thread_group threads;
for (int i =1; i<=3;++i)
{
threads.push_back(std::jthread{&worker_thread, io_svc, i});
}
// std::chrono::milliseconds sleep_times {1000};
// std::this_thread::sleep_for(sleep_times);
io_svc->post(boost::bind(&throw_an_exception, io_svc, 1));
io_svc->post(boost::bind(&throw_an_exception, io_svc, 2));
io_svc->post(boost::bind(&throw_an_exception, io_svc, 3));
io_svc->post(boost::bind(&throw_an_exception, io_svc, 4));
io_svc->post(boost::bind(&throw_an_exception, io_svc, 5));
return 0;
}
输出是
The program will exit once all work has finished.
Thread1started
我认为发生死锁是因为我在多个地方添加了 std::lock_guard
如果我删除下面代码中的锁保护,就不会出现死锁,但只是想知道使用 std::lock_guard 的最佳解决方案是什么?
void throw_an_exception(std::shared_ptr<boost::asio::io_service> io_svc, int counter)
{
{
//commment below will addredd deadlock issue
//std::lock_guard l {global_stream_lock};
std::cout << "Throw Exception " << counter << "\n" ;
}
throw(std::runtime_error("The Exception !!!"));
}
我找到了解决方案。
lock_guard 只能用于一种目的。显然上面是一个错误
try{
std::lock_guard l {global_stream_lock};
iosvc->run();
std::cout<<"Thread "<<i<<"End \n";
}
catch(std::exception &ex){
{
std::cout << "Message: " << ex.what() << ".\n";
}
}
更改为
try{
iosvc->run();
{
std::lock_guard l {global_stream_lock};
std::cout<<"Thread "<<i<<"End \n";
}
}
catch(std::exception &ex){
{
std::lock_guard l {global_stream_lock};
std::cout << "Message: " << ex.what() << ".\n";
}
}
教科书中的变量 global_stream_lock 应该仅用于 cout。
但是如果有人能引导我完成它,我将不胜感激。
当我在 lock_guard 范围中包含 iosvc->run(); 时,死锁是如何触发的?