29 June 2023

C++ 核心指南目录

“Prefer gsl::joining_thread over std::thread

理由

joining_thread 会在线程作用域范围结束的时候联合(join)。分离的线程很难监控。很保证在分离的线程正确无误。

坏例子

void f() { std::cout << "Hello "; }

struct F {
    void operator()() const { std::cout << "parallel world "; }
};

int main()
{
    std::thread t1{f};      // f() executes in separate thread
    std::thread t2{F()};    // F()() executes in separate thread
}  // spot the bugs

例子

void f() { std::cout << "Hello "; }

struct F {
    void operator()() const { std::cout << "parallel world "; }
};

int main()
{
    std::thread t1{f};      // f() executes in separate thread
    std::thread t2{F()};    // F()() executes in separate thread

    t1.join();
    t2.join();
}  // one bad bug left

注意

把一直常存的线程设为全局,外层作用域,或放在自由存储区。不要 detach()

注意

因为老的代码和第三方库都在用 std::thread ,此条规则很难遵循。

强化

标记使用了 std::thread 的地方:

  • 建议使用 gsl::joining_thread 或 C++20 的 std::jthread
  • 如果线程要分离,建议所有权转移到外部作用域
  • 警告不确定线程是要联合还是分离