C ++ 11 std :: threads与posix线程


157

为什么在实践中我应该选择一个或另一个?除了std::thread一堂课,技术上有什么区别?


5
在实践中,您应该使用std::async
Stephan Dollberg,2012年

从同样的问题@bamboon这遭罪的std::thread
冈瑟Piez

2
@hirschhornsalz来自编译器支持视图,是的。从技术的角度来看,它提供了异常安全,可以提供std::threadpthreads不提供。
斯蒂芬·多尔伯格

15
投票重新开放。对“技术差异”的要求使这一问题客观地得到解决。高投票数表明其他人认为该职位具有建设性和帮助作用。
阿德里安·麦卡锡

Answers:


121

如果要在许多平台上运行代码,请使用Posix Threads。它们几乎随处可见,并且已经相当成熟。另一方面,如果您仅使用Linux / gcc,std::thread则非常好-它具有更高的抽象级别,一个非常好的接口,并且可以与其他C ++ 11类很好地配合使用。

std::thread不幸的是,即使C ++ 11似乎可用,C ++ 11 类也无法在每个平台上可靠地工作。例如,在本机Android std::thread或Win64中,它不起作用或存在严重的性能瓶颈(截至2012年)。

一个很好的替代品是boost::thread-它非常类似于std::thread(实际上是同一作者的)并且可靠地工作,但是,当然,它引入了第三方库的另一个依赖关系。


编辑:截至2017年,std::thread大多数版本都可在本机Android上运行。某些类,例如std::timed_mutex,仍未实现。


19
您是否有证据支持这些“性能瓶颈”主张?而且,std::thread它的raii样式也不错,因为它可以处理C ++异常,而pthread不能开箱即用。
杰西·古德

9
现在在2014年,这个答案仍然有效吗?
不动声色

25
那从2017年初开始呢?
rmobis '17

9
那现在在2017年中期呢?
Lightness Races in Orbit

14
那现在呢,在2018年中期?
陈力

59

std::thread库在支持pthread的环境中(例如:libstdc ++)在pthread之上实现。

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


4
+1我指出了最重要的一点,即std :: thread提供了更高级别的抽象。
2012年

33

std::thread 提供跨Windows,MacOS和Linux等不同平台的可移植性。

如@hirshhornsalz在下面的评论中以及相关答案https://stackoverflow.com/a/13135425/1158895中提到的,std::thread可能并非在所有平台上都完整。即便如此(在不久的将来),它也应该比的更受青睐,pthread因为它可以使您的应用程序更加适应未来。


2
实际上,std :: threads可在支持C ++ 11的所有平台上提供可移植性,而POSIX线程仅可用于POSIX平台(或力求最小兼容性的平台)。
Tobias Langner

1
从实际的观点来看,这是错误的。实际上,我几个月前就此推理做出了决定-这是一个重大错误。实际上,您必须boost::thread在Win64或Bionic(Android)上使用,因为std::thread它仍然缺少很大的部分,而在Linux上std::thread似乎已经很成熟了。
冈瑟·皮埃兹

1
@hirschhornsalz,我的回答是指出c ++ 11线程实现与pthread相比具有可移植性。OP并没有询问Boost的问题,但它也具有便携性。
布雷迪

3
@hirschhornsalz,关于您的负面语气和不使用线程的指责,它们只是不合逻辑的,我不应该付出太多努力。我认为至少值得一提的是,提出更具建设性的意见是指出您尝试在不同平台上使用std :: thread时遇到的麻烦。
布雷迪2012年

3
总而言之,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。
冯·2012年

7

对我而言,决定性的技术差异是与pthread相反,std中没有信号处理原语。仅使用std无法在Unix进程中正确指示信号处理是AFAIK使用std :: thread的一个令人衰弱的缺陷,因为它阻止了建立真正的多线程信号处理模式来处理专用信号中的所有信号。线程并将其阻止在其余部分。您必须假定std :: thread是使用pthreads实现的,并希望在使用pthread_sigmask时获得最佳效果。在企业的Unix系统编程中,正确处理信号是不可协商的。

截至2016年,std :: thread是一个玩具; 就那么简单。


7
我不同意。信号的大量使用是一种在大多数应用中都可以避免的设计模式。
ErikAlapää16年

此外,std::thread带来了pthread所没有的类型安全性。
alfC

-3

OpenMP的

http://www.openmp.org/

是基于SMP的标准化多线程标准,已经在Linux和Windows上运行了十多年。默认情况下,OpenMP可用于所有编译器,包括GCC和Microsoft Visual Studio。

使用OpenMP时需要注意的一件事是,如果线程多于CPU内核,则性能会因上下文切换相关的开销而下降。要记住的第二件事是,实际的操作系统级别线程的初始化相对昂贵。初始化只需几分之一秒,但是在某些应用程序中,非常小的分数会累积起来,从而产生相当大的开销。

对于与并发相关的软件体系结构要求,您可能需要搜索一些“轻量级线程”或“绿色线程”的实现,而不是使用OpenMP。区别在于OpenMP线程是实际的,操作系统级别的线程,但“绿色线程”可以只是通过使用少量实际线程执行的“模拟线程”。


6
毫不恭敬,但这与主要问题有何关系?
SRG
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.