std::thread 不带参数的构造函数
std::thread constructor with no parameter
根据cppreference.com,
std::thread
没有参数的构造函数意味着:
Creates new thread object which does not represent a thread.
我的问题是:
- 为什么我们需要这个构造函数?如果我们使用这个构造函数创建一个
thread
,我们以后如何"assign"一个线程函数?
- 为什么我们没有一个 "run(function_address)" 方法,这样当构造时没有参数,我们可以为
thread
指定一个函数 "run"。
- 或者,我们可以构造一个带有可调用参数(函数、函子等)的
thread
,但稍后调用一个"run()"方法来实际执行线程。为什么std::thread
不是这样设计的?
提供了默认构造函数,以便可以创建 "empty" thread
对象。并非所有 thread
个对象都会在构造所述对象时与执行线程相关联。考虑何时 thread
是某种类型的成员并且该类型具有默认构造函数。考虑另一种情况,thread
类型没有 "suspended" 线程的概念,即它不能在挂起状态下创建。
thread
类型没有某种 "run" 方法,因为最初的设计决策 (IIRC) 之一是 "strong" 与 thread
对象和执行线程。允许 thread
为 "moved" 使该意图更清晰(在我看来)。因此,将 thread
对象的实例移动到 "empty" 对象比尝试 "run" 一个 thread
.
更清晰
可以想象,您可以创建某种提供 "run" 方法的包装器 class,但我认为这可能是一个更窄的用例,可以是 解决了 API 的 std::thread
class.
编辑: 也许让我们首先评论最后一部分:
3.2 Why std::thread is not designed in this way?
我不知道为什么(肯定有优点和缺点 - 请参阅 Jonathan Wakely 的回答以了解有关其背后理性的更多详细信息),但似乎 c++11 std::thread
是建模的比例如更接近 pthreads QT 或 Java 的 QThread/Thread
classes,这可能是您混淆的根源。
关于您的其他问题:
1.1 why do we need this constructor?
您可能想要创建一个 std::thread
变量但不要直接启动线程(例如 class 成员变量或静态数组的元素,es 由 alangab 显示)。它与可以在没有文件名的情况下创建的 std::fstream
没有太大区别。
1.2 And if we create a thread using this constructor, how can we "assign" a thread function later?
例如:
std::thread myThread;
// some other code
myThread = std::thread(foo());
- 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.
我不知道,为什么要这样设计,但我看不出 run
方法与上述语法相比有什么好处。
3.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.
您可以通过创建 lambda 或 std::function
对象来模拟这一点,并在您想要 运行 函数时创建线程。
auto myLambda = [=]{foo(param1, param2);};
// some other code
std::thread myThread(myLambda);
如果您想使用您描述的语法,我建议您编写自己的 Thread
包装器 class(应该只需要几十行代码)(可选)确保线程在包装器销毁时分离或连接,在我看来,这是 std::thread
.
的主要问题
您的问题表明可能存在一些混淆,清楚地将 执行线程 的概念与 std::thread
类型的概念分开会很有帮助,并将两者都来自 "thread function".
的想法
- 一个执行线程表示程序中的控制流,可能对应于内核管理的OS线程。
- 类型
std::thread
的对象可以与 执行线程 相关联,或者它可以是 "empty" 并且不引用任何 执行线程.
- 标准 C++ 中没有 "thread function" 这样的概念。通过将任何函数传递给
std::thread
对象的构造函数,可以在新的 执行线程 中 运行。
- why do we need this constructor?
构建不引用 执行线程 的空状态。您可能希望 class 的成员变量是 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?
您 "assign" 使用 "assignment" :-)
但是你没有给它分配 "thread function",那不是 std::thread
的目的。您为其分配另一个 std::thread
:
std::thread t;
std::thread t2{ func, args };
t = std::move(t2);
考虑创建新的执行线程,而不是"assigning a thread function"。您不只是分配一个函数,这就是 std::function
的用途。您正在请求 运行 时间来创建一个新的 执行线程 ,它将由 std::thread
对象管理。
- 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
对象来启动新的执行线程。如果您希望该执行线程与现有对象相关联,那么您可以通过 move-assigning 或交换来实现。
- 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
的工作是管理 执行线程 在你想调用它之前不要持有可调用对象。
默认构造函数让您可以创建线程数组:
thread my_threads[4];
for (int i=0; i<4; i++)
{
thread temp(func,...);
my_threads[i]=move(temp);
}
使用默认构造函数创建的线程 "become" 使用移动构造函数的 "real" 线程。
如果 need/like.
,您可以将线程与标准容器一起使用
根据cppreference.com,
std::thread
没有参数的构造函数意味着:
Creates new thread object which does not represent a thread.
我的问题是:
- 为什么我们需要这个构造函数?如果我们使用这个构造函数创建一个
thread
,我们以后如何"assign"一个线程函数? - 为什么我们没有一个 "run(function_address)" 方法,这样当构造时没有参数,我们可以为
thread
指定一个函数 "run"。 - 或者,我们可以构造一个带有可调用参数(函数、函子等)的
thread
,但稍后调用一个"run()"方法来实际执行线程。为什么std::thread
不是这样设计的?
提供了默认构造函数,以便可以创建 "empty" thread
对象。并非所有 thread
个对象都会在构造所述对象时与执行线程相关联。考虑何时 thread
是某种类型的成员并且该类型具有默认构造函数。考虑另一种情况,thread
类型没有 "suspended" 线程的概念,即它不能在挂起状态下创建。
thread
类型没有某种 "run" 方法,因为最初的设计决策 (IIRC) 之一是 "strong" 与 thread
对象和执行线程。允许 thread
为 "moved" 使该意图更清晰(在我看来)。因此,将 thread
对象的实例移动到 "empty" 对象比尝试 "run" 一个 thread
.
可以想象,您可以创建某种提供 "run" 方法的包装器 class,但我认为这可能是一个更窄的用例,可以是 解决了 API 的 std::thread
class.
编辑: 也许让我们首先评论最后一部分:
3.2 Why std::thread is not designed in this way?
我不知道为什么(肯定有优点和缺点 - 请参阅 Jonathan Wakely 的回答以了解有关其背后理性的更多详细信息),但似乎 c++11 std::thread
是建模的比例如更接近 pthreads QT 或 Java 的 QThread/Thread
classes,这可能是您混淆的根源。
关于您的其他问题:
1.1 why do we need this constructor?
您可能想要创建一个 std::thread
变量但不要直接启动线程(例如 class 成员变量或静态数组的元素,es 由 alangab 显示)。它与可以在没有文件名的情况下创建的 std::fstream
没有太大区别。
1.2 And if we create a thread using this constructor, how can we "assign" a thread function later?
例如:
std::thread myThread;
// some other code
myThread = std::thread(foo());
- 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.
我不知道,为什么要这样设计,但我看不出 run
方法与上述语法相比有什么好处。
3.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.
您可以通过创建 lambda 或 std::function
对象来模拟这一点,并在您想要 运行 函数时创建线程。
auto myLambda = [=]{foo(param1, param2);};
// some other code
std::thread myThread(myLambda);
如果您想使用您描述的语法,我建议您编写自己的 Thread
包装器 class(应该只需要几十行代码)(可选)确保线程在包装器销毁时分离或连接,在我看来,这是 std::thread
.
您的问题表明可能存在一些混淆,清楚地将 执行线程 的概念与 std::thread
类型的概念分开会很有帮助,并将两者都来自 "thread function".
- 一个执行线程表示程序中的控制流,可能对应于内核管理的OS线程。
- 类型
std::thread
的对象可以与 执行线程 相关联,或者它可以是 "empty" 并且不引用任何 执行线程. - 标准 C++ 中没有 "thread function" 这样的概念。通过将任何函数传递给
std::thread
对象的构造函数,可以在新的 执行线程 中 运行。
- why do we need this constructor?
构建不引用 执行线程 的空状态。您可能希望 class 的成员变量是 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?
您 "assign" 使用 "assignment" :-)
但是你没有给它分配 "thread function",那不是 std::thread
的目的。您为其分配另一个 std::thread
:
std::thread t;
std::thread t2{ func, args };
t = std::move(t2);
考虑创建新的执行线程,而不是"assigning a thread function"。您不只是分配一个函数,这就是 std::function
的用途。您正在请求 运行 时间来创建一个新的 执行线程 ,它将由 std::thread
对象管理。
- 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
对象来启动新的执行线程。如果您希望该执行线程与现有对象相关联,那么您可以通过 move-assigning 或交换来实现。
- 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
的工作是管理 执行线程 在你想调用它之前不要持有可调用对象。
默认构造函数让您可以创建线程数组:
thread my_threads[4];
for (int i=0; i<4; i++)
{
thread temp(func,...);
my_threads[i]=move(temp);
}
使用默认构造函数创建的线程 "become" 使用移动构造函数的 "real" 线程。
如果 need/like.
,您可以将线程与标准容器一起使用