异步基于任务的并发

时间:2015-12-22 10:26:45

标签: c++ multithreading asynchronous concurrency

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()究竟返回了什么?

基于任务的并发性意味着工作将在所有可用线程之间平均分配。

1 个答案:

答案 0 :(得分:2)

12个唯一线程ID是指软件线程而不是硬件线程。在Windows(7或10)的任务管理器面板中,我看到了成千上万的线程数,这些线程还是基于时间分片在可用硬件线程上并发执行的软件线程。

异步适用于基于任务的并发。与此有关的一些问题如下:

  1. 如果未指定启动策略,则无法保证任务将在单独的线程中执行。实现可能会根据某些条件(例如,太多线程)选择在同一线程中执行任务。

  2. 如果未捕获异步调用的返回值(future <>),则将立即阻止当前线程的执行。与串行程序相同。即使指定了异步策略,也会发生这种情况。

  3. 异步返回的future <>的析构函数将阻止执行(如果异步调用的执行尚未完成)。