CC++ 线程中止

CC++ 线程中止,第1张

今天主管找我了一个方案设计提到一个他们用Java做的一个状态机,他的做法是,当基于状态设计模式的状态机的实际状态发生变化时,执行相应的动作(也就是调用对应的函数),他的做法是将一个继承了Runnable的对象提交到一个线程池里面,听到这都没问题,问题在于他说可以从外部中止当前执行的任务,他的意思是调用他Java的Thread类的interrupt函数来打断当前线程中函数的执行。我当时有点迷惑,因为C++标准库里并没有提供这样的 *** 作,甚至在C++20 引入的基于std::thread的封装的jthread也不能做到这一点,标准库之所以这样做是因为这样做,十有八九会导致内存泄漏,文件描述符泄露,甚至造成死锁的风险。那么标注库不支持, *** 作系统有能不能做到呢?答案是可以的。下面以基于POSIX的pthread库为例:

auto fun = [] {
  for (;;) {
    std::this_thread::sleep_for(300ms);
    std::cout << "thread:" << std::this_thread::get_id() << "\n";
  }
};

auto main() -> int {
  auto th = std::thread(fun);
  
  std::this_thread::sleep_for(2s);
  ::pthread_cancel(th.native_handle());

  th.join();

  return {};
}

输出为:

thread:140679200679488
thread:140679200679488
thread:140679200679488
thread:140679200679488
thread:140679200679488
thread:140679200679488

可以看到纸打印了6次(有限次)就退出了。th.native_handle()返还出系统软件线程句柄

struct Main {
  Main() { std::cout << "ctor\n"; }
  ~Main() { std::cout << "dtor\n"; }
};

auto fun = [] {
  auto ptr = new Main();
  
  for (;;) {
    std::this_thread::sleep_for(300ms);
    std::cout << "thread:" << std::this_thread::get_id() << "\n";
  }
};

auto main() -> int {
  auto th = std::thread(fun);
  
  std::this_thread::sleep_for(2s);
  ::pthread_cancel(th.native_handle());

  th.join();

  return {};
}
ctor
thread:140618021824064
thread:140618021824064
thread:140618021824064
thread:140618021824064
thread:140618021824064
thread:140618021824064

可以看到这里虽然指针变量出栈,但是其引用的Main对象泄露了

很简单做法改为智能指针

auto fun = [] {
  auto ptr = std::make_shared<Main>();
  
  for (;;) {
    std::this_thread::sleep_for(300ms);
    std::cout << "thread:" << std::this_thread::get_id() << "\n";
  }
};
ctor
thread:140608551016000
thread:140608551016000
thread:140608551016000
thread:140608551016000
thread:140608551016000
thread:140608551016000
dtor

不过这里创建在堆上的对象相较于栈上对象没有一点优势,创建和释放都没栈上对象来得方便。所以我感觉一个注定被中止的线程,内部执行的函数一定要十分注意,一定要遵循RAII,这一点包括fd的管理,要用基于RAII的对象管理。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/919809.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存