c++ - 无参数的 std::thread 构造函数

标签 c++ multithreading c++11 stdthread

根据 cppreference.com , 这 std::thread 没有参数的构造函数意味着:

Creates new thread object which does not represent a thread.

我的问题是:

  1. 为什么我们需要这个构造函数?如果我们使用这个构造函数创建一个thread,我们以后如何“分配”一个线程函数?
  2. 为什么我们没有一个“run(function_address)”方法,这样当构造时没有参数,我们可以指定一个函数来为那个线程“运行”。
  3. 或者,我们可以构造一个带有可调用参数(函数、仿函数等)的线程,但稍后调用“run()”方法实际执行该线程。为什么std::thread不是这样设计的?

最佳答案

您的问题表明可能存在一些混淆,将 执行线程 的概念与 std::thread 类型清楚地分开会很有帮助,并且将两者与“线程函数”的概念分开。

  • 执行线程代表程序中的控制流,可能对应于内核管理的操作系统线程。
  • std::thread 类型的对象可以与一个执行线程相关联,或者它可以是“空的”并且不引用任何执行线程
  • 在标准 C++ 中没有“线程函数”这样的概念。通过将函数传递给 std::thread 对象的构造函数,任何函数都可以在新的执行线程中运行。
  1. why do we need this constructor?

构造不引用执行线程 的空状态。您可能想要一个属于 std::thread 的类的成员变量,但不想立即将其与执行线程 相关联。所以您默认构造它,然后启动一个新的执行线程并将它与std::thread 成员变量相关联。或者你可能想这样做:

std::thread t;
if (some_condition) {
  t = std::thread{ func1, arg1 };
}
else {
  auto result = some_calculation();
  t = std::thread{ func2, arg2, result };
}

默认构造函数允许创建对象 t,直到需要时才启动新的执行线程

And if we create a thread using this constructor, how can we "assign" a thread function later?

您使用“赋值”来“赋值”:-)

但是你没有给它分配一个“线程函数”,这不是 std::thread 的目的。您将另一个 std::thread 分配给它:

std::thread t;
std::thread t2{ func, args };
t = std::move(t2);

考虑创建一个新的执行线程,而不是“分配一个线程函数”给某物。您不只是分配一个函数,这就是 std::function 的用途。您正在请求运行时创建一个新的执行线程,它将由 std::thread 对象管理。

  1. Why don't we have a "run(function_address)" method so that when constructed with no parameter, we can specify a function to "run" for that thread.

因为你不需要它。您可以通过构造带参数的 std::thread 对象来启动新的执行线程。如果您希望该执行线程与现有对象相关联,那么您可以通过移动分配或交换来实现。

  1. Or, we can construct a thread with a callable parameter(function, functors, etc.) but call a "run()" method to actually execute the thread later. Why std::thread is not designed in this way?

为什么要这样设计?

std::thread 类型用于管理执行线程,而不是持有供以后使用的可调用对象。如果你想创建一个稍后可以在新的执行线程上运行的可调用对象,在 C++ 中有很多方法可以做到这一点(使用 lambda 表达式,或 std::bind ,或 std::function,或 std::packaged_task,或自定义仿函数类型)。 std::thread 的工作是管理一个执行线程,在您想要调用它之前不要持有可调用对象。

关于c++ - 无参数的 std::thread 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35037723/

相关文章:

c++ - 为什么当构造函数引用字符串时无法正确打印?

c++ - 为什么对 c 和 c++ 使用 gcc 和 g++ 编译器驱动程序

c++ - 实现基于模板的运算符分配函数时出现链接错误

c# - 如何向应用程序添加暂停/恢复功能?

c++ - 在 C++ 中对普通整数使用原子操作

没有模板参数的 C++ 模板?

c++ - 结构化绑定(bind)的 decltype(auto) 是否应该是引用?

c# - 托管线程是否可能与其自身存在竞争条件

python - 如何锁定从两个不同终端调用的 python main 方法

c++ - 如何使用指针访问对 vector 的元素?