关于C ++:C ++ 11 std :: thread与Windows CreateThread

C++11 std::thread vs windows CreateThread

哪个选项更适合在Visual C ++下创建(和管理)线程:C ++ 11 std::threadWinAPI函数(例如CreateThread_beginthreadex等),为什么?


可移植性

std::thread是C ++ 11标准的新功能-使用它,您可以跨支持C ++ 11的编译器以C ++编写可移植代码。您可以在其中感觉到future

它基于boost::thread,后者支持不支持C ++ 11的较旧的编译器,这使得向其他平台的移植更加容易。

如果您需要使用平台特定的技巧,则可以使用std::thread::native_handle

CreateThread特定于WinAPI,这意味着编写不可移植的代码。而且,此API相当旧,使用起来更加不便。

区域情报研究所

WinAPI是一种C API,不鼓励使用现代C ++良好实践。您创建的每个线程原语,都必须稍后手动销毁。

C ++ 11中的线程库不是这种情况,这使得更高级的抽象更易于编写。尽管std::thread仍处于较低级别(您的线程为.join().detach(),或者线程析构函数将终止您的程序),但C ++ 11线程库具有std::lock_guard和其他用于支持RAII的锁类用于互斥。

尽管C ++ 11具有一些更高级别的抽象,例如std::async用于异步启动函数,但它不提供其他抽象,例如线程池,因此您可能要使用其他库。

类型安全

WinAPI只能调用具有特定签名的函数指针-容易出现与类型安全,对象生存期和内存管理不当相关的错误。

std::thread可以调用任何可调用对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// call free-standing function in a separate thread
std::thread first(func);

// call free-standing function with arguments (1, 2), in a separate thread
std::thread second(func, 1, 2);

// call static member function in a separate thread
std::thread third(&A::static_memfun);

// call non-static member of a temporary in a separate thread
std::thread fourth(&A::memfun, A());

//call std::function in a separate thread
std::function<void(int)> callback = std::bind(func, 1, _1);
std::thread fifth(callback, 2);

// call a function object
Functor f;
std::thread sixth(f);

TL; DR:在新的C ++代码中没有理由使用WinAPI线程作为主要的线程机制。


跨平台是一个小好处。真正的好处在于界面。 std::thread提供关于线程清理的RAII保证,并且支持任意函数对象参数,而不仅仅是函数指针。 std::thread是CreateThreadEX上的C ++ 11包装,这是有原因的。

恰如其分,std :: thread是一个糟糕的API。如果您自己创建线程,则可能做错了。使用真正的线程API,例如Intel的TBB或Microsoft的PPL,它们远远优于可怕的std::thread,甚至使CreateThreadEx更糟。 std::thread就像是,"嘿,我为您提供了跨平台的mmap,因此您可以在上面编写自己的malloc,请尽情享受!"。


您可能应该使用std :: thread。

std :: thread是(新)标准的一部分,并且可移植。

除非您只针对Windows,并且需要使用WinAPI与线程进行交互,否则std :: thread是必经之路。