int
main()
{
std::mutex io;
std::vector<std::future<void>> futures;
std::cout << "Main id: " << std::this_thread::get_id() << std::endl;
for (int i = 0; i < 12; ++i) {
std::future<void> f = std::async(std::launch::async, [&]{
std::this_thread::sleep_for(std::chrono::seconds(10));
io.lock();
std::cout << "Thread id: " << std::this_thread::get_id() << std::endl;
io.unlock();
});
futures.push_back(std::move(f));
}
for (auto& f : futures) {
f.wait();
}
}
我在几个博客上看到我不能将async
用于基于任务的并发,因为它没有在线程上均匀地分发tasks
,所以我创建了一个小的测试程序。 / p>
Main id: 140673289357120
Thread id: 140673241089792
Thread id: 140673215911680
Thread id: 140673232697088
Thread id: 140673224304384
Thread id: 140673207518976
Thread id: 140673199126272
Thread id: 140673165555456
Thread id: 140673190733568
Thread id: 140673173948160
Thread id: 140673182340864
Thread id: 140673157162752
Thread id: 140673148770048
但输出不是我预期的。我的机器有两个带有超线程的内核,它给了我4个线程,但是查看线程ID似乎它们都是独一无二的。
async可以用于基于任务的并发吗?
this_thread::get_id()
究竟返回了什么?
基于任务的并发性意味着工作将在所有可用线程之间平均分配。
答案 0 :(得分:2)
12个唯一线程ID是指软件线程而不是硬件线程。在Windows(7或10)的任务管理器面板中,我看到了成千上万的线程数,这些线程还是基于时间分片在可用硬件线程上并发执行的软件线程。
异步适用于基于任务的并发。与此有关的一些问题如下:
如果未指定启动策略,则无法保证任务将在单独的线程中执行。实现可能会根据某些条件(例如,太多线程)选择在同一线程中执行任务。
如果未捕获异步调用的返回值(future <>),则将立即阻止当前线程的执行。与串行程序相同。即使指定了异步策略,也会发生这种情况。
异步返回的future <>的析构函数将阻止执行(如果异步调用的执行尚未完成)。