存档

文章标签 ‘mutex’

C++11/14 新特性 (多线程)

2017/03/28 8,968

在 C++11 之前 ,C++ 标准并没有提供统一的并发编程标准,也没有提供语言级别的支持。这导致我们在编写可移植的多线程程序时很不方便,往往需要面向不同的平台进行不同的实现,或者引入一些第三方平台,如Boost,pthread_win32 等。 从C++11开始 ,对并发编程进行了语言级别的支持,使用使用C++进行并发编程方便了很多。这里介绍C++11并发编程的相关特性。

1 线程

1.1 线程的创建

std::thread 的构造函数如下:

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

我们只需要提供线程函数或函数对象,即可以创建线程,并可以同时指定线程函数的参数。

#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 来创建线程(其实就是使用函数对象创建线程)。

线程不可以被复制,但是可以被移动:
继续阅读