在 C++20 中使用 std::jthread 和逗号运算符并行执行多个操作

Executing several actions in parallel with std::jthread and comma operator in C++20

在 C++20 中我们得到了一个新的线程-class std::jthread 不同于旧的 std::thread waits 用于析构函数中的线程终止。因此,使用未命名的 jthread 对象和逗号运算符并行执行多个操作变得容易:

#include <thread>
#include <iostream>

int main() {
    std::jthread{ []{ std::cout << "Hello from new thread\n"; } },
        std::cout << "Hello from main thread\n";
}

这很好用,演示:https://gcc.godbolt.org/z/YPW8bq7jK

很遗憾,Visual Studio2019在这里发出警告:

warning C4834: discarding return value of function with 'nodiscard' attribute

因为std::jthread构造函数在里面声明为[[nodiscard]]。据我所知,标准不需要此属性:https://timsong-cpp.github.io/cppwp/n4861/thread.jthread.class.

这只是 MSVC STL 中的一个错误,还是确实存在与这种 jthread 用法相关的风险?

为什么不这样写呢?

#include <thread>
#include <iostream>

int main()
{
     // Note: Just like the original
     //       It is indeterminate what order these are
     //       printed out in. 
     std::jthread  parallelThread{ []{ std::cout << "Hello from new thread\n"; } };
     std::cout << "Hello from main thread\n";
}

这完全一样,但使用命名变量而不是不可见的临时变量。

作为旁注,您可以通过确保知道 jthread 何时被销毁来强制执行命令。

#include <thread>
#include <iostream>

int main()
{
     {
         std::jthread  parallelThread{ []{ std::cout << "Hello from new thread\n"; } };
     }
     std::cout << "Hello from main thread\n";
}

there is really some risk associated with such jthread-usage?

定义“此类用途”和“一些风险”。

nodiscard 属性完全适合 jthread 的构造函数。是的,您 可以 编写代码,其中创建和丢弃 jthread 对象是一件有意义的、实用的事情。但即使它有意义且实用,您仍然不应该这样做。它以一种绝对不会增加任何价值的方式在您的代码中变得可爱。它看起来 像一个错误,最好不要编写看起来与损坏代码几乎相同的代码。

尝试编写清晰、干净的代码,不需要有人知道 C++ 逗号运算符及其与子表达式的关系的详细信息,以便准确地衡量其操作。

是的,标准库实现可以出于任何原因发出警告。只要格式正确的程序按照标准的描述成功编译和执行,实现就是有效的。