c++ std::lock_guard在异常处理中死锁

nmpmafwu  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(208)

我在一个文档中读到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 !!!"));
}

blmhpbnm

blmhpbnm1#

我找到解决办法了。
lock_guard应该只用于一个目的。显然上面是一个bug

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";
  }
}


text book中的变量global_stream_lock应该只用于cout。
但如果有人能帮我解释一下我会很感激的。
当我在lock_guard作用域中包含**iosvc->run();**时,死锁是如何触发的?

9vw9lbht

9vw9lbht2#

std::mutex global_stream_lock;替换为std::recursive_mutex global_stream_lock;

相关问题