C++11标准线程与POSIX线程比较

187

在实践中,我应该选择哪一个?除了 std::thread 是一个类之外,它们的技术差异是什么?


5
实际应用中,您应使用 std::async - Stephan Dollberg
@bamboon 这个也遇到了和 std::thread 相同的问题。 - Gunther Piez
2
从编译器支持的角度来看,是的,它提供了异常安全性,而std::threadpthreads则没有。 - Stephan Dollberg
https://dev59.com/QUjSa4cB1Zd3GeqPJOGu - Ciro Santilli OurBigBook.com
5个回答

138
如果你想要在多个平台上运行代码,选择 POSIX 线程是一个不错的选择。它们几乎到处都可以使用并且技术比较成熟。另一方面,如果你只使用 Linux/gcc,那么 std::thread 很适合 - 它抽象级别更高,接口非常好,并且可以与其他 C++11 类很好地配合使用。
然而,C++11 的 std::thread 类在每个平台上(尚)不能可靠工作,即使 C++11 可用。例如,在本机 Android 或 Win64 上,std::thread 不起作用或存在严重的性能瓶颈(截至2012年)。
一个很好的替代品是 boost::thread - 它非常类似于 std::thread(实际上是同一作者),并且可靠工作,但是,当然,它会引入第三方库的依赖。
编辑:截至2017年,std::thread 在本机 Android 上大部分情况下都能够正常工作。某些类,如 std::timed_mutex 仍未实现。

23
你有没有任何证据来支持这些"性能瓶颈"的说法?此外,std::thread及其RAII风格很好,因为它可以处理C++异常,而pthread不能直接处理。 - Jesse Good
2
你使用了mingw版本的std::thread吗?相比MSVC,我会预期性能会有所下降,因为它们使用了pthreads的端口,但是MSVC应该是没问题的。 - Jesse Good
3
@Serthy 至少在某种程度上 - 我正在努力交叉编译一个简单的程序(https://dev59.com/34zda4cB1Zd3GeqPhhKo)。 它在我愉快的 gcc / linux 环境中工作,但当我尝试编译 ARMv7 时,应用程序会立即终止。 相对于 std::thread,pthreads 是令人头疼的,但这个答案很准确地指出:“如果你想在许多平台上运行代码,请选择 Posix Threads”。 - darkpbj
4
现在和将来都应该使用std::thread。它是跨平台的,正如另一个回答者所说,具有未来性,并且不会遇到性能瓶颈问题。 - KeyC0de
6
自2015年以来,std::thread在Windows上运行良好。相反,在VC++中,POSIX线程不存在。 - rustyx
显示剩余7条评论

74

std::thread库是在支持pthreads(例如:libstdc++)的环境中基于pthread实现的。

我认为两者之间的最大区别是抽象性。 std::thread是一个C++类库。 std::thread库包含许多抽象特性,例如:作用域锁、递归互斥锁、未来/承诺设计模式实现等。


40

std::thread 提供了在不同平台(如 Windows、MacOS 和 Linux)之间的可移植性。

正如下面评论中 @hirshhornsalz 所提到的和相关答案 https://dev59.com/qGcs5IYBdhLWcg3wGgJc#13135425std::thread 在所有平台上可能尚未完整。但即便如此,(在不久的将来)它应该比 pthread 更优秀,因为它可以使您的应用程序更加未来化。


2
实际上,std::threads 可以在支持 C++11 的所有平台上提供可移植性,而 POSIX 线程仅在 POSIX 平台(或力求一些最小兼容性的平台)上可用。 - Tobias Langner
2
从实际角度来看,这是错误的。我几个月前就基于这种推理做出了决定 - 这是一个重大错误。在实践中,你必须在Win64或Bionic(Android)上使用boost::thread,因为std::thread仍然缺少很多部分,在Linux上,std::thread似乎相当成熟。 - Gunther Piez
4
简而言之,C++11的std::thread只能在较新版本的GCC中使用。在Visual Studio中它不完整,因此无法在Windows上使用。当然,在UNIX商业编译器(例如Solaris上的Sun Studio、HP-UX上的HP aCC以及AIX上的IBM vacpp)中完全缺失。因此,如果你的目标平台仅限于Linux,那么C++11的std::thread是可以的;如果你还需要Windows或其他UNIX系统,则应选择boost::thread。 - vond
std::thread 提供了在不同平台上的可移植性,如 Windows、MacOS 和 Linux。 - user457015
这个声明是11年前发表的,可能在所有平台上还不完整。 - undefined

12

对我来说,在标准库中缺少信号处理原语与pthreads相比是技术上的决定性差异。使用仅限于std无法正确指示Unix进程中的信号处理,据我所知,这是使用std::thread的致命缺陷之一,因为它阻止了您设置真正的多线程信号处理模式来在专用线程中处理所有信号并在其余部分中阻止它们。您被迫假设std::thread使用pthreads实现,并在使用pthread_sigmask时抱最大希望。在Unix系统编程中,适当处理信号是不可妥协的企业级需求。

截至2016年,std::thread只能算是玩具,就这么简单。


9
我不同意。而且,在大多数应用程序中可以避免过度使用信号的设计模式。 - Erik Alapää
此外,std::thread 带来了 pthread 没有的类型安全性。 - alfC

0
我刚刚发现,std::thread对线程数量有限制,而POSIX线程没有这个限制。似乎C++中的线程创建会检查一个名为DefaultTasksMaxsystemd属性,而Posix的libpthread没有进行这个检查。
我很快会更新这个答案,并提供一些C++和C的代码片段来证明这一点。

2
你的孩子在哪里? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接