【问题标题】:Async for task based concurrency基于任务的并发的异步
【发布时间】:2015-12-22 10:26:45
【问题描述】:
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 均匀地分布在线程上,所以我创建了一个小型测试程序。

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

但输出不是我所期望的。我的机器有 2 个带有超线程的内核,这给了我 4 个线程,但是查看线程 ID 似乎它们都是独一无二的。

异步可以用于基于任务的并发吗?

this_thread::get_id() 究竟返回了什么?

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

【问题讨论】:

  • 回答你的第二个问题,get_id 函数返回一个std::thread::id 对象。究竟是什么取决于实现。
  • 至于你的第一个问题,你应该检查例如this std::async reference,表示“模板函数 async 异步运行函数 f可能在一个单独的线程中可能 i> 成为线程池的一部分)”(强调我的)。要回答您的问题,必须考虑到这一点,并且知道您所说的“基于任务的并发”是什么意思。
  • 查看此问答以获取类似信息stackoverflow.com/questions/15666443/…

标签: c++ multithreading asynchronous concurrency


【解决方案1】:

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

async 适用于基于任务的并发。这有一些问题如下:

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

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

  3. async 返回的future 的析构函数会阻塞执行(如果async 调用的执行没有完成)。

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2013-02-13
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 2020-03-12
    相关资源
    最近更新 更多