我正在阅读关于 std::async 和 std::launch::async 的内容,并阅读了该策略,可调用对象将在新线程中调用。
所以为了测试,我做了如下操作:
struct Wrapper
{
void consume()
{
std::cout << "consume " << std::this_thread::get_id() << std::endl;
std::for_each(arr.begin(), arr.end(), [](int val) {std::cout << val; });
}
bool produce()
{
std::cout << "produce " << std::this_thread::get_id() << std::endl;
arr = { 1,0,3 };
return true;
}
};
int main()
{
std::cout << "main " << std::this_thread::get_id() << std::endl;
Wrapper wrap;
std::future<bool> fut = std::async(std::launch::async, &Wrapper::produce, &wrap);
if (fut.get())
std::async(std::launch::async, &Wrapper::consume, &wrap);
}
因此基于此,我将排除 3 个线程:
- 线程 1:主线程
- 线程 2:std::async 的第一次调用(执行 produce fct)
- 线程 3:std::async 的第二次调用(执行消费 fct)
当我运行我得到的程序时:
为什么std::async的两次调用有相同的线程ID??
谢谢。
最佳答案
标准说的是 std::async
:
If
launch::async
is set inpolicy
, callsINVOKE(DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...)
as if in a new thread of execution [...]
重要的部分是“好像在一个新的执行线程中”。实现必须表现得好像可调用对象是从新线程调用的,但它不需要实际在新线程上运行。提供这种余地是为了让标准库实现者可以重用相同的线程,也许是通过保持一个方便的线程池处于待机状态(threadpool 模式),这比每次调用 std::async
时创建和销毁威胁的响应更快。尽管从理论上讲,实现也可以选择每次都创建和销毁线程,或者执行符合标准要求的任何其他操作。
关于c++ - std::launch::async 不同线程的数量是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52332032/