哪个选项更适合在Visual C ++下创建(和管理)线程:C ++ 11 std::thread
或WinAPI
函数(例如CreateThread
,_beginthreadex
等。)为什么?
答案 0 :(得分:34)
std::thread
是C ++ 11标准的新手 - 有了它,您可以在支持C ++ 11的编译器中用C ++编写可移植代码。你可以感受到future
。
它基于boost::thread
,它支持不支持C ++ 11的旧编译器 - 这使得移植到其他平台变得更加容易。
如果您需要使用特定于平台的技巧,std::thread::native_handle
是可行的方法。
CreateThread
特定于WinAPI,这意味着编写非可移植代码。此外,这个API很老,使用起来也不方便。
WinAPI是一种C API,不鼓励现代C++ good practices。您创建的每个线程原语都必须稍后手动销毁。
C ++ 11中的线程库不是这种情况,这使得更高级别的抽象更容易编写。虽然std::thread
仍然相当低级(您的线程是.join()
或.detach()
,或者线程析构函数将终止您的程序),但C ++ 11线程库已{{1}和其他用于支持互斥体RAII的锁类。
虽然C ++ 11有一些更高级别的抽象,比如std::lock_guard
用于异步启动函数,但它不提供其他抽象,如线程池,所以你可能想要使用其他库。
WinAPI只能调用具有特定签名的函数指针 - 这容易出现与类型安全性,对象的生命周期和内存管理不善相关的错误。
std::async
可以调用任何可调用对象:
std::thread
TL; DR :没有理由使用WinAPI线程作为新C ++代码中的主要线程机制。
答案 1 :(得分:5)
跨平台性是一个小小的好处。真正的好处在于界面。 std::thread
提供了关于线程清理的RAII保证,并且支持任意函数对象参数而不仅仅是函数指针。 std::thread
是CreateThreadEX上的C ++ 11包装器,出于某种原因,它就是这种方式。
正如旁注,std :: thread是一个可怕的,糟糕的API。如果你自己创建线程,那么你可能做错了。使用真正的线程API,如英特尔的TBB或微软的PPL,它们非常优于可怕的 std::thread
而更糟糕 CreateThreadEx 。 std::thread
就像是,“嘿伙计们,我为你提供了跨平台mmap
,所以你可以自己编写malloc
,享受!”。
答案 2 :(得分:3)
你应该使用std :: thread。
std :: thread是(新)标准的一部分,并且是可移植的。
除非您只针对Windows并且需要使用WinAPI与线程进行交互,否则std :: thread是可行的方法。