C++11 之多线程(一)

一,多线程概述
    线程(Thread)是程序中独立执行的指令流,通常是系统调度的基本单位。含有两个或两个以上线程的程序就称为多线程程序,在硬件允许的情况下多个线程可以彼此独立的并行执行。在许多情况下都需要使用多线程,比如:

        1,程序需要进行一些IO操作,IO操作通常需要一些时间才能完成,在这段时间线程就会被阻塞。使用多线程就可以启动一个新的线程去等待IO操作完成,而当前线程就可以不被阻塞的继续执行别的工作;
         2,在多核心处理器的机器上执行计算密集型的程序。使用多线程就可以将计算工作切分成多个独立的计算工作交给多个线程在CPU的不同核心上并行计算。
       C++11开始提供了多线程的支持。标准库提供std::thread类来创建和管理线程,std::future类模板来获取异步操作的结果。
        
         std::thread 类
        下面的代码演示了使用std::thread类在主线程中创建一个线程对象td,创建的线程执行函数thread_proc中的代码输出线程id。主线程调用thread对象td的join函数等待线程执行结束。
void thread_proc(int a)
{
	cout << "thread id = " << this_thread::get_id() << endl;
}

int main()
{
	thread td(thread_proc, 1);
	td.join();

	getchar();
	return 0;
}


        线程的执行体
        std::thread的执行体并不要求必须是普通的函数,任何可调用的对象都是可以的。举例如下:
   
        1. Lambda 表达式
int main()
{
	thread td([](int a, int b){
		cout << a << " + " << b << " = " << a + b << endl;
	}, 1, 2);
	td.join();

	getchar();
	return 0;
}

        2. 重载了operator() 的类的对象
int main()
{
	thread td(Student(), 1, 2);
	td.join();

	getchar();
	return 0;
}

         3. 此外还可以使用 std::bind 表达式和Lambda表达式间接的让非静态成员函数作为执行体
            使用 std::bind表达式绑定对象和其非静态成员函数
int main()
{
	Student s;
	thread td(std::bind(&Student::add, &s, 2, 3));
	td.join();

	getchar();
	return 0;
}

        4. 使用Lambda表达式调用对象的非静态成员函数
int main()
{
	Student s;
	thread td([&s](){
		s.add(2, 3);
	});
	td.join();

	getchar();
	return 0;
}


        等待线程执行结束
        无论是使用std::bind表达式还是Lambda表达式都需要注意保证obj对象不能再函数执行完成前被销毁。
        需要特别注意的是std::thread对象有个成员函数joinable用于判断线程对象是否是可以join的。当线程对象被析构的时候如果对象joinable() == true会导致std::terminate()被调用。所以让thread对象被正确的析构就需要知道什么情况下joinable()为false了。
        1,默认构造函数构造的thread对象
        默认构造函数构造的对象不代表任何线程,所以joinable为false。

int main()
{
	thread td;
	cout << "td.joinable() = " << std::boolalpha << td.joinable() << endl;

	getchar();
	return 0;
    输出 td.joinable() = flase

         2, 调用过join的thread对象
            通过对join成员函数的调用可以使joinable为true的thread对象在join返回后变为false

int main()
{
	thread td([](){});
	cout << "td.joinable() = " << std::boolalpha << td.joinable() << endl;
	td.join();
	cout << "td.joinable() = " << std::boolalpha << td.joinable() << endl;

	getchar();
	return 0;
}

输出结果: td.joinable() = true
            td.joinable() = false
            
            3, 调用过detach的 thread对象

            通过对detach成员函数的调用允许线程不再受thread对象管理,所以thread对象的joinable自然变成false了。
int main()
{
	thread td([](){});
	cout << "td.joinable() = " << std::boolalpha << td.joinable() << endl;
	td.detach();
	cout << "td.joinable() = " << std::boolalpha << td.joinable() << endl;

	getchar();
	return 0;
}
输出结果: td.joinable() = true
            td.joinable() = false


猜你喜欢

转载自blog.csdn.net/zyx_0604/article/details/80691580