加入线程:“避免资源死锁”

Posted

技术标签:

【中文标题】加入线程:“避免资源死锁”【英文标题】:joining a thread: "resource deadlock avoided" 【发布时间】:2019-05-06 14:40:00 【问题描述】:

我使用一个封装了 boost::asio::io_service 的 c++ 类。

class ioservice 
 public:
  static IoService& getInstance() 
    static IoService instance;
    return instance;
  
  void start() 
    _ioServiceThread = std::thread(&IoService::run, this);
  
  void stop() 
    _ioService.stop();
    _ioServiceThread.join();
  
  void run() 
   _ioService.run();
  

 private:
  IoService();
  ~IoService();
  IoService(const IoService& old) = delete;
  IoService(const IoService&& old) = delete;
  IoService& operator=(const IoService& old) = delete;
  IoService& operator=(const IoService&& old) = delete;

  boost::asio::io_service _ioService;
  std::thread _ioServiceThread;
;

但是当我调用 stop 方法时,程序在加入时崩溃了:

terminate called after throwing an instance of 'std::system_error'
what():  Resource deadlock avoided
Aborted

你怎么看?

【问题讨论】:

提供MCVE,io_services没有join方法。显示创建 IoService 的代码以及如何调用 start/stop。 IoService 析构函数的主体在哪里? 我的错,这是一个错字。我在 std 线程上调用 join ! 【参考方案1】:

这是线程尝试加入自身时出现的错误。

所以听起来您的问题是您正在从由io_service 调用的处理程序函数调用stop() 方法。

【讨论】:

我不太明白……当我调用 _ioService.stop() 方法时,看起来我没有退出 _ioService.run();方法。是预期的吗?也许这就是加入不起作用的原因……? 问题是调用IoService::stop()的线程上下文。您正在从处理程序函数调用它,这意味着它正在由运行 io_service::run() 的线程运行,这与您尝试加入的线程相同。您需要从不同的线程调用::stop() 函数。 为了更清楚地了解我如何使用 IoService 类,我有另外两个类 A 和 B,它们有一个私有 IoService& _ioService;,我在 A 的析构函数中调用 _ioService.stop()。不好吗? 重要的是哪个线程运行它 - 那么,哪个线程最终运行 A 的析构函数?

以上是关于加入线程:“避免资源死锁”的主要内容,如果未能解决你的问题,请参考以下文章

关于线程池的工作队列类型

线程同步

多线程

关于线程同步

线程同步的方法

Java笔记——关于线程同步