2017/03/28
7,320
在 C++11 之前 ,C++ 标准并没有提供统一的并发编程标准,也没有提供语言级别的支持。这导致我们在编写可移植的多线程程序时很不方便,往往需要面向不同的平台进行不同的实现,或者引入一些第三方平台,如Boost,pthread_win32 等。 从C++11开始 ,对并发编程进行了语言级别的支持,使用使用C++进行并发编程方便了很多。这里介绍C++11并发编程的相关特性。
1 线程
1.1 线程的创建
std::thread 的构造函数如下:
1 2 |
template< class Function, class... Args > explicit thread( Function&& f, Args&&... args ); |
我们只需要提供线程函数或函数对象,即可以创建线程,并可以同时指定线程函数的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <iostream> #include <thread> using namespace std; void func(const string& str){ cout<<str<<endl; } class FuncCls{ public: void operator()(){ cout<<"Funcls called"<<endl; } }; int main(void){ thread t1(func,"Hello World"); FuncCls fcls; thread t2(fcls); if(t1.joinable()){ t1.join(); } t2.join(); return 0; } |
join函数将会阻塞线程,直到线程函数执行完毕,主线程才会接着执行。如果线程函数有返回值,返回值将被忽略。 在使用线程对象的过程中,我们需要注意线程对象的生命周期。如果线程对象先于线程函数结束,那么将会出现不可预料的错误。可以通过线程阻塞的方式来等待线程函数执行完(join),或让线程在后台执行。 如果不希望线程被阻塞,可以调用线程的 detach() 函数,将线程与线程对象分离。但需要注意的是,detach 之后的线程无法再使用join来进行阻塞了,即detach之后的线程,我们无法控制了。当我们不确定一个线程是否可以join时,可以先使用 thead::joinable() 来进行判断。
另外,我们还可以通过 std::bind, lambda 来创建线程(其实就是使用函数对象创建线程)。
线程不可以被复制,但是可以被移动:
继续阅读