C ++ 11:std :: thread汇集了吗?

时间:2012-10-20 23:02:36

标签: c++ multithreading c++11 stdthread

在C ++ 03中,我使用pthread和自建的线程池,它总是保持一些线程运行(因为pthread_create很慢),这样我就可以在不考虑的情况下为小任务启动线程关于性能问题。

现在,在C ++ 11中,我们有std::thread。我想标准没有说明具体的实现,所以我的问题是标准的库实现。他们通常选择合并方法来构建std::thread s是否便宜(例如,不会在posix上调用pthread_create),或者std::thread只是一个包装器?

换句话说,C ++ 11中仍然推荐使用线程池,还是应该只在需要时创建std::thread并将性能提升到标准库?

4 个答案:

答案 0 :(得分:23)

通常,std::thread应该是底层系统原语的最小包装器。例如,如果您在pthread平台上,则可以使用以下程序进行测试,无论您创建多少个线程,它们都使用唯一的pthread_t ID创建(这意味着它们已创建)在飞行中而不是从线程池中借用):

#include <assert.h>
#include <mutex>
#include <set>
#include <thread>
#include <vector>

#include <pthread.h>

int main() {
  std::vector<std::thread> workers;
  std::set<long long> thread_ids;
  std::mutex m;
  const int n = 1024;

  for (int i = 0; i < n; ++i) {
    workers.push_back(std::thread([&] {
      std::lock_guard<std::mutex> lock(m);
      thread_ids.insert(pthread_self());
    }));
  }
  for (auto& worker : workers) {
    worker.join();
  }
  assert(thread_ids.size() == n);

  return 0;
}

所以线程池仍然很有意义。也就是说,我看过一个视频,其中C ++委员会成员讨论了关于std::async(IIRC)的线程池,但我现在找不到它。

答案 1 :(得分:11)

std::thread是一个执行线程。期。它来自哪里,如何到达那里,是否存在一些“实际”线程等等,都与标准无关。只要它像一个线程,它就可以是std::thread

现在,std::thread是一个真实的操作系统线程,而不是从线程池或其他任何东西中提取的东西。但是理论上C ++ 11允许将std::thread实现为从池中提取的东西。

答案 2 :(得分:5)

在抽象成本方面,

std::thread应该是非常便宜的,它是低级别的东西。据我了解,标准库实现可能只是尽可能地封装底层的OS机制,因此您可以假设线程创建的开销与类似或等效。

我不知道任何具体的实现,但是通过阅读 C ++ Concurrency In Action ,我的第二手理解是标准建议他们使用最有效的方法实用。作者肯定认为与DIY相比,成本会或多或少地微不足道。

这个库在概念上与Boost类似,所以我想用Boost实现得出一些结论不会太牵强。

基本上,我认为没有直接回答你的问题,因为它没有明确说明。虽然听起来我们会更有可能看到非常薄的包装器实现,但我不认为库编写器如果能提供效率优势就不会使用线程池。

答案 3 :(得分:2)

首先,正如您所提到的,C ++标准基本上没有指定库实现。 但是C ++标准库的实现者应该遵守“as-if”规则。

例如,这意味着std::thread的构造函数应该像 那样创建 新线程,无论是底层API的薄包装还是高效实现,如线程池。 (这里,'thread'表示C ++ 11规范中的抽​​象执行线程,而不是具体的OS本机线程)

关于线程池实现;

  • C ++编译器和库应该正确处理C ++线程特定的资源(即thread_local变量),它们应该在运行时协同工作。
  • 即使满足上述条件,似乎也无法与OS特定的线程资源(Windows的TLS,pthread的TSS等)合作。

因此,我假设大多数std::thread实现只是底层线程API的包装。