簡體   English   中英

在一次調用C ++ 11中啟動多個線程

[英]Launching Multiple Threads in a single call C++ 11

據我了解,在C ++ 11中創建多個線程的典型方法是:

int num_threads = 10;
std::thread threads[num_threads];
for(int i = 0; i < num_threads; ++i)
{
    threads[i] = std::thread(doSomething);
}
// Call join if you need all threads completion
for(int i = 0; i < num_threads; ++i)
{
    threads[i].join();
}

是否可以一次性啟動線程,而不是使用循環順序啟動每個線程。 我知道在CUDA中,線程是同時啟動的,不需要單獨啟動每個線程。 想知道在C ++ 11中是否有可能實現類似的目標

是的,您可以生成一個將在一個語句中啟動n線程(邏輯上)的操作。

template<class F>
std::future<void> launch_tasks( F&& f, size_t n ) {
  if (n==0) { // ready future case, launch 0 threads:
    std::promise<void> p;
    p.set_value();
    return p.get_future();
  }
  std::vector<std::future<void>> results;
  results.reserve(n-1);
  for (size_t i = 0; i < n-1; ++i) {
    results.push_back(
      std::async(
        std::launch::async,
        f, i
      )
    );
  }
  // last thread waits on the previous threads before finishing:
  return std::async(
    std::launch::async,
    [results=std::move(results),f=std::forward<F>(f)]{
      f(results.size());
      for (auto&& others:results)
        others.wait();
    }
  };
}

只需調用launch_tasks( [](size_t i) { /* code */ }, n )將啟動n任務,每個任務都有一個索引。 返回的future將阻止所有已完成的任務,而無需為該任務使用額外的線程。

最后一個lambda使用C ++ 14功能(通用捕獲)。 您可以這樣編寫一個函數對象:

template<class F>
struct work_then_wait {
  F f;
  std::vector<std::future<void>> futures;
  void operator()()const{
    f(futures.size());
    for (auto&& f:results)
      f.wait();
  }
};

然后

return work_then_wait<typename std::decay<F>::type>{
  std::forward<F>(f),
  std::move(results)
};

而不是lambda,它是等效的,但用C ++ 11編寫。

一個更簡單的版本在所有等待所有期貨的任務上使用std::async( std::launch::deferred ,但是這使wait_until和其他定時等待返回的future無效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM