std::lock_guard 异常处理中的死锁

问题描述 投票:0回答:1

众所周知,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 !!!"));
}
c++ multithreading boost deadlock
1个回答
0
投票

我找到了解决方案。

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(); 时,死锁是如何触发的?

© www.soinside.com 2019 - 2024. All rights reserved.