用c ++ 11等价物replaceboost :: thread和boost :: mutex是否明智?

动机:我考虑的原因是我的天才项目经理认为提升是另一个依赖,它是可怕的,因为“你依靠它”(我试图解释提升的质量,然后放弃了一段时间:( )。为什么我想要做的更小的原因是我想学习c ++ 11的特性,因为人们会开始编写代码,所以:

  1. #include<thread> #include<mutex>和boost等价物之间是否存在1:1映射?
  2. 你会考虑一个好主意,用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 vs std::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 ++ 11 std::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::mutexstd::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标准。

Interesting Posts