栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C/C++ 线程中止

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C/C++ 线程中止

今天主管找我了一个方案设计提到一个他们用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 << "ctorn"; }
  ~Main() { std::cout << "dtorn"; }
};

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
(); 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的对象管理。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/878118.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号