繁体   English   中英

C++20 使用 std::stop_token 停止分离的 std::jthread

[英]C++20 stopping a detached std::jthread using an std::stop_token

在 C++20 中, std::jthread被引入为std::thread的更安全版本; 据我了解,其中std::jthread会在线程退出时自行清理。

此外,引入了协作取消的概念,以便std::jthread管理一个处理底层线程状态的std::stop_source ::stop_source ,这个std::stop_source公开了一个std::stop_token ,外人可以使用它来读取状态线程的理智。

我所拥有的是这样的。

class foo {
  std::stop_token stok;
  std::stop_source ssource;

public:
  void start_foo() {
    // ...
    auto calculation = [this](std::stop_token inner_tok) {
      // ... (*this is used here)
      while(!inner_tok.stop_requested()) {
        // stuff
      }
    }
    auto thread = std::jthread(calculation);
    ctok = thread.get_stop_token();
    ssource = thread.get_stop_source();

    thread.detach(); // ??
  }

  void stop_foo() {
    if (ssource.stop_possible()) {
      ssource.request_stop();
    }
  }

  ~foo() {
   stop_foo();
  }
}

注意foostd::shared_ptr管理,并且没有公共构造函数。

沿着这条线的某个地方,另一个线程可以在可能分离的线程上调用foo::stop_foo()

我所做的安全吗?

此外,在分离线程时,C++ 句柄不再与正在运行的线程关联,由操作系统管理,但线程是否继续从std::stop_source接收停止通知?

有没有更好的方法来实现我所需要的? 在 MVSC 中,这似乎不会引发任何异常或停止程序执行,我已经做了很多测试来验证这一点。

那么,这个解决方案是否可移植?

如果线程在foo被销毁后访问this ,那么您编写的内容可能是不安全的。 这也有点令人费解。 一种更简单的方法是将jthread粘贴在结构中......

class foo {
  std::jthread thr;

public:
  void start_foo() {
    // ...
    jthr = std::jthread([this](std::stop_token inner_tok) {
      // ... (*this is used here)
      while(!inner_tok.stop_requested()) {
        // stuff
      }
    });
  }

  void stop_foo() {
    jthr.request_stop();
  }

  ~foo() {
     stop_foo();
     // jthr.detatch(); // this is a bad idea
  }
}

为了匹配代码的语义,您可以在析构函数中取消注释jthr.detach() ,但这实际上是一个坏主意,因为那时您最终可能会在线程仍在访问它时销毁foo 我上面写的代码是安全的,但是很明显,无论哪个线程删除了对foo的最后一个引用,都必须等待jthread退出。 如果这真的令人无法忍受,那么也许您想更改 API 以在线程本身中粘贴一个shared_ptr ,这样如果在删除最后一个外部引用后线程仍在运行,则该线程可以销毁foo

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM