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

NoS*_*tAl 150 c++ multithreading boost mutex c++11

动机:我之所以考虑是因为我的天才项目经理认为提升是另一种依赖,而且它很可怕,因为"你依赖它"(我试着解释提升的质量,然后放弃一段时间后:(我想做的更小的原因是我想学习c ++ 11的功能,因为人们会开始在其中编写代码.所以:

  1. 是否有1:1的映射#include<thread> #include<mutex>和boost等效?
  2. 你会考虑用c ++ 11的
    东西替换boost东西吗?我的用法是原始的,但有什么例子,当std没有提供什么提升?或者(亵渎)反之亦然?

PS我使用GCC所以标题就在那里.

Ant*_*ams 188

Boost.Thread和C++ 11标准线程库之间有几点不同:

  • Boost支持线程取消,C++ 11线程不支持
  • C++ 11支持std::async,但Boost不支持
  • Boost具有boost::shared_mutex多读取器/单写入器锁定功能.类似std::shared_timed_mutex的仅在C++ 14(N3891)之后std::shared_mutex可用,而仅在C++ 17(N4508)之后可用.
  • C++ 11超时与Boost超时不同(尽管现在很快就会改变Boost.Chrono).
  • 一些名称是不同的(例如boost::unique_futurevs std::future)
  • 参数传递语义std::thread不同于boost::thread--- Boost使用boost::bind,它需要可复制的参数.std::thread允许仅移动类型,例如std::unique_ptr作为参数传递.由于使用boost::bind,占位符的语义(如_1嵌套绑定表达式)也可能不同.
  • 如果没有显式调用join(),detach()那么boost::thread析构函数和赋值运算符将调用detach()被销毁/赋值的线程对象.使用C++ 11 std::thread对象,这将导致调用std::terminate()和中止应用程序.

为了澄清关于仅移动参数的观点,以下是有效的C++ 11,并将int临时的所有权转移std::unique_ptrf1新线程启动时的参数.但是,如果您使用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)));
Run Code Online (Sandbox Code Playgroud)

如果您正在使用Boost,那么如果您的编译器支持它,您可以相对轻松地切换到C++ 11线程(例如,Linux上的最新版本的GCC具有-std=c++0x模式中可用的C++ 11线程库的大部分完整实现).

如果您的编译器不支持C++ 11线程,那么您可能能够获得第三方实现,例如Just :: Thread,但这仍然是一个依赖项.

  • 是的,自从我写这篇文章以来,Boost.Thread已经变得更接近C++ 11标准了,主要是因为Vicente Botet的工作. (4认同)
  • 绊倒我的另一个小问题是:在boost中,正在运行的线程的析构函数将其分离(http://www.boost.org/doc/libs/1_47_0/doc/html/thread/thread_management.html#thread.thread_management. thread.destructor),而在C++中,正在运行的线程的析构函数调用terminate()(FDIS 30.3.1.3) (3认同)
  • 在C++ 11中,`try_scoped_lock`功能由`std :: unique_lock`覆盖.有一个构造函数接受一个互斥锁和`std :: try_to_lock`,然后在互斥锁上调用`try_lock()`而不是`lock()`.见http://www.stdthread.co.uk/doc/headers/mutex/unique_lock/try_lock_constructor.html (3认同)
  • `shared_mutex`文档位于http://www.boost.org/doc/libs/1_47_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.shared_mutex.您可以将互斥锁锁定为共享或独占,然后使用相应的解锁功能.您也可以使用RAII类型执行此操作(`shared_lock`采用共享读锁,`lock_guard`和`unique_lock`采用独占锁定).我试图澄清关于仅移动类型的观点. (2认同)

Ale*_*x B 24

std::thread在很大程度上模仿boost::thread,有一些差异:

  • boost的不可复制,单句柄映射到一个os线程,语义被保留.但是这个线程是可移动的,允许从工厂函数返回线程并放入容器中.
  • 该提案增加了取消boost::thread,这是一个重大的复杂因素.此更改不仅对线程有影响,而且对C++线程库的其余部分也有很大影响.人们相信,这种巨大的变化是有道理的,因为它的好处.
    • 线程析构函数现在必须在分离之前调用cancel,以避免在取消父线程时意外泄漏子线程.
    • 现在需要显式分离成员启用分离而不取消.
  • 线程句柄和线程标识的概念已分为两类(它们是同一个类boost::thread).这是为了支持更容易操作和存储线程标识.
  • 能够创建一个保证比较等于没有其他可连接线程的线程id(boost::thread没有这个).这对于想要知道它是否由与前一个调用相同的线程执行的代码来说很方便(递归互斥体是一个具体的例子).
  • 存在一个"后门"来获取本机线程句柄,以便客户端可以根据需要使用底层操作系统来操作线程.

这是从2007年开始,所以有些点不再有效:现在boost::thread有一个native_handle功能,并且,正如评论者指出的那样,std::thread不再有取消.

我找不到boost::mutex和之间的任何显着差异std::mutex.

  • 是的,提升中的取消称为"中断".是的,这是一个旧提案.最新的C++ 11标准公开草案(包括线程库)是http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf (4认同)
  • `std :: thread`没有取消; 它是`boost :: thread`! (2认同)

ks1*_*322 6

有一个原因是不迁移到std::thread.

如果您使用静态链接,std::thread由于这些gcc错误/功能而变得无法使用:

也就是说,如果你打电话std::thread::detachstd::thread::join它会导致异常或崩溃,boost::thread在这些情况下工作正常.

  • 我们可以假设这些错误是固定的,因为现在是2016年吗?这些错误发布于2012年,从gcc 4.9.2开始,它正式支持C++ 11,所以我们不能在官方支持之前抱怨C++ 11. (4认同)

Nic*_*ith 6

企业案例

如果您正在为需要在中等到大量操作系统上运行的企业编写软件,并因此在这些操作系统上使用各种编译器和编译器版本(尤其是相对较旧的版本)进行构建,我的建议是远离C++ 11现在一共.这意味着你不能使用std::thread,我建议使用boost::thread.

基础/技术创业案例

如果你正在编写一个或两个操作系统,你肯定知道你只需要构建一个主要支持C++ 11的现代编译器(例如VS2015,GCC 5.3,Xcode 7),而你还没有依赖于升级库,那么std::thread可能是一个不错的选择.

我的经验

我个人偏爱硬化,使用频繁,高度兼容,高度一致的库,例如boost与非常现代的替代品.对于诸如线程之类的复杂编程主题尤其如此.此外,我长期以来boost::thread在各种环境,编译器,线程模型等方面取得了巨大成功(并且总体上提升了).当我选择时,我选择了boost.