用c ++ 11等价物replaceboost :: thread和boost :: mutex是否明智?
动机:我考虑的原因是我的天才项目经理认为提升是另一个依赖,它是可怕的,因为“你依靠它”(我试图解释提升的质量,然后放弃了一段时间:( )。为什么我想要做的更小的原因是我想学习c ++ 11的特性,因为人们会开始编写代码,所以:
- 在
#include<thread> #include<mutex>
和boost等价物之间是否存在1:1映射? - 你会考虑一个好主意,用c + + 11replace提升的东西
东东。 我的用法是原始的,但有没有例子时,标准不提供什么提升呢? 或者(亵渎)反之亦然?
PS我使用GCC所以标题在那里。
Boost.Thread和C ++ 11标准线程库有几个区别:
- Boost支持线程取消,C ++ 11线程不支持
- C ++ 11支持
std::async
,但Boost不支持 - Boost有一个
boost::shared_mutex
用于多读取器/单写入器locking。 类似的std::shared_timed_mutex
仅在C ++ 14( N3891 )之后才可用 ,而std::shared_mutex
仅在C ++ 17( N4508 )之后才可用 。 - C ++ 11超时与Boost超时不同(尽pipe现在Boost.Chrono已经被接受)。
- 一些名称是不同的(例如
boost::unique_future
vsstd::future
) -
std::thread
的parameter passing语义不同于boost::thread
— Boost使用boost::bind
,它需要可复制的参数。std::thread
允许移动types,如std::unique_ptr
作为parameter passing。 由于使用了boost::bind
,嵌套绑定expression式中占位符(如_1
的语义也可能不同。 - 如果你没有明确地调用
join()
或detach()
那么boost::thread
析构函数和赋值操作符将调用被销毁/分配给的线程对象的detach()
。 使用C ++ 11std::thread
对象,这将导致对std::terminate()
的调用并中止应用程序。
为了澄清关于仅移动参数的问题,以下是有效的C ++ 11,并且在新线程启动时将int
的所有权从临时std::unique_ptr
转移到f1
的参数。 但是,如果使用boost::thread
那么它将不起作用,因为它在内部使用boost::bind
,并且不能复制std::unique_ptr
。 在GCC中提供的C ++ 11线程库中也存在一个错误,它阻止了这个工作,因为它在实现中也使用了std::bind
。
void f1(std::unique_ptr<int>); std::thread t1(f1,std::unique_ptr<int>(new int(42)));
如果你正在使用Boost,那么如果你的编译器支持的话,你可以相当轻松地切换到C ++ 11线程(例如,最近版本的GCC在linux上有一个C ++ 11线程库的大部分完整的实现,在-std=c++0x
模式)。
如果您的编译器不支持C ++ 11线程,那么您可能能够获得第三方实现,如Just :: Thread ,但这仍然是一个依赖项。
std::thread
主要是在boost::thread
之后build模的,有一些不同之处 :
- boost的不可复制的单处理映射到一个os线程,语义被保留。 但是这个线程是可移动的,以允许从工厂函数返回线程并放入容器。
- 这个build议增加了对
boost::thread
取消,这是一个非常复杂的问题。 这个改变不仅对线程有很大的影响,而且对C ++线程库的其他部分也有很大的影响。 相信这个巨大的变化是有道理的,因为这个好处。
- 线程析构函数现在必须在分离之前调用取消,以避免父线程被取消时意外泄漏子线程。
- 现在需要明确的分离成员来启用分离而不取消。
- 线程句柄和线程标识的概念被分成了两个类(它们是
boost::thread
中的同一个类)。 这是为了支持更容易的线程标识的操作和存储。- 已经添加了能够创build一个保证比较等于没有其他可连接线程的线程ID(
boost::thread
没有这个)。 对于想要知道它是否被前一个调用执行的代码(recursion互斥是一个具体的例子),这是很方便的。- 存在一个“后门”来获取本地线程句柄,以便客户端可以根据需要使用底层操作系统来操作线程。
这是从2007年开始的,所以有些观点不再有效: boost::thread
现在有一个native_handle
函数,正如评论者指出的那样, std::thread
不再有取消。
我找不到boost::mutex
和std::mutex
之间的任何显着差异。
有一个原因不迁移到std::thread
。
如果你正在使用静态链接,由于这些gcc的bug /function, std::thread
变得不可用:
也就是说,如果调用std::thread::detach
或者std::thread::join
,会导致exception或崩溃,而boost::thread
在这些情况下可以正常工作。
企业案例
如果你正在为企业编写软件,而这些软件需要运行在各种各样的操作系统上,并且因此在这些操作系统上build立了各种编译器和编译器版本(特别是比较老的版本),我的build议是远离C ++ 11现在完成。 这意味着你不能使用std :: thread,而且我会推荐使用boost :: thread。
基本/技术启动案例
如果您正在编写一个或两个操作系统,那么您肯定知道您将只需要使用大多数支持C ++ 11的现代编译器(例如VS2015,GCC 5.3,Xcode 7)来构build,而且您还没有依赖于boost库,那么std :: thread可能是一个不错的select。
我的经验
我个人偏向于强化,大量使用,高度兼容,高度一致的库,如增强型与非常现代的替代型。 对于线程等复杂的编程主题尤其如此。 另外,我在很多环境,编译器,线程模型等方面都经历了boost :: thread(以及一般的boost)的巨大成功。当我selectboost时,我selectboost。
在Visual Studio 2013中, std::mutex
行为与boost::mutex
行为不同,这导致了一些问题(请参阅此问题 )。
我试图从std中使用shared_ptr而不是boost,而且实际上在这个类的gcc实现中发现了一个bug。 我的应用程序崩溃,因为析构函数调用两次(这个类应该是线程安全的,不应该产生这样的问题)。 搬到boost :: shared_ptr之后,所有的问题都消失了。 目前C ++ 11的实现还不成熟。
Boost也有更多的function。 例如标准版本的头文件不提供串行器到stream(即cout << duration)。 Boost拥有许多使用自己等等的库,但是不能与std版本合作。
总结一下,如果你已经有了一个使用boost编写的应用程序,保持你的代码是安全的,而不是花费一些努力去转换到C ++ 11标准。