C++11从入门到精通 第六章-并发与多线程 第二节 线程启动,结束,创建线程方法,join(),detach(),joinable()方法

一 范例演示线程的创建

1.thread 类

前面的内容知道,程序运行起来,生成一个进程,该进程所属的主线程从main方法开始自动运行直到return 结束。

我们创建一个线程,也要从一个函数开始运行,一旦这个函数运行起来,就代表着我们这个线程开始运行,一旦这个函数运行结束,就代表着这个线程运行结束。

C++11提供了thread 这个类,因此第一步就是要 #include <thread>

使用 thread 类 ,构建对象的时候,传递的参数是一个方法,我们这里 是:mythreadmethod().

暂时没有传递参数。

我们知道,当主线程执行完毕后,进程也就挂了。如果主线程都执行完毕了,子线程还没有执行完毕,那么一般情况下,进程就会有runtime exception。

因此,在一般情况下,我们要让主线程等待子进程结束。因而引出了join()方法的使用

// 002createthread_join_detach.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <thread>
using namespace std;

void mythreadmethod() {
	cout << "mythreadmethod start..." << endl;

	cout << "mythreadmethod end..." << endl;
}
int main()
{
    std::cout << "Hello World start!\n";

	thread mythread(mythreadmethod);//这句话的意思是:1.创建一个子线程;2.该线程执行起点是mythreadmethod方法;3.mythreadmethod方法就已经抢占CPU开始执行,但是并不一定能抢过其他线程。
	mythread.join();//join方法的意思是:作用是阻塞主线程,让主线程等待子线程执行完毕,然后子线程和主线程汇合,然后再沿着主线程没有完成代码往下走。

	std::cout << "Hello World end!\n";
}

2.join()

作用是阻塞主线程,让主线程等待子线程执行完毕,然后子线程和主线程汇合,然后再沿着主线程没有完成代码往下走。

2.1 主线程阻塞等待,直到子线程执行完毕

2.2 子线程只能就算执行完毕了呢?就是创建子线程时,传递的方法 执行 完成了

2.3 不加 join()方法会怎么样呢?不会编辑错误,但是运行时候,会有几率 runtime exception。

        原因也很简单,当主线程先于子线程执行完成的case发生的时候:

                主线程结束 = 进程结束

                但是这时候子线程没有结束,那么这时候子线程依附于谁存在呢?换句话说:子线程中的临时变量,方法等,谁来回收呢?因此就有runtime exception

3.detach() 老师不建议使用,坑太多,除非有必要,

从上面知道,传统多线程程序:主线程使用join()方法等到子线程执行完毕,然后再执行自己的逻辑。

那么能不能主线程自己结束就结束,不用管子线程呢?

detach()方法就是干这个的。

使用detach()的意思是:

3.1主线程不和子线程汇合了

3.2子线程原本关联的主线程,现在就不在和主线程关联了,这个子线程就会驻留在后台运行。

3.3该子线程会被C++运行时库接管,当子线程执行完毕后,由运行时库(实际上是守护线程,这个要知道linux的一些相关进程线程的知识才懂,如果不懂,就大致理解为有人接管就可以了)清理该线程相关资源

3.4 detach 的坑 - 后续章节上专门研究

当主线程结束的时候,主线程中的值能否使用?

如果线程对象传递的方法中有参数,且这个参数是从主线程传递过去的,当主线程运行结束后,那么这个参数能否使用?

4.joinable()

该函数的作用是判断,join()huozhe detach()方法能否使用?

运用时机:当程序很大的,最好判断一下。

结论:

当使用了join方法后,就不能再次使用join 和 detach方法了

当使用了detach方法后,就不能再次使用join 和 detach方法了

二 用类创建线程以及注意问题

1.使用类对象,这个类对象需要实现operator()()方法,即()的重载。

class AA {
public:
	void operator()() {
		cout << "class AA operator()() start..." << endl;
		cout << "class AA operator()() end..." << endl;
	}
	int age;
};


//运行结果为:
//Hello World0 start!
//class AA operator()() start...Hello World1 end!
//	Hello World2 end!
//	Hello World3 end!
//	Hello World4 end!
//
//	class AA operator()() end...
//	Hello World5 end!
//	Hello World6 end!
void main() {
	AA aa;
	std::cout << "Hello World0 start!\n";
	thread mythread(aa);
	std::cout << "Hello World1 end!\n";
	std::cout << "Hello World2 end!\n";
	std::cout << "Hello World3 end!\n";
	std::cout << "Hello World4 end!\n";

	mythread.join();

	std::cout << "Hello World5 end!\n";
	std::cout << "Hello World6 end!\n";

}

三用lambda表达式

[](){}

//运行结果为:
//Hello World0 start!
//mylambdathread start...Hello World1 end!
//Hello World2 end!
//Hello World3 end!
//Hello World4 end!
//
//mylambdathread end...
//Hello World5 end!
//Hello World6 end!
void main() {
	std::cout << "Hello World0 start!\n";
	auto mylambdathread = []() {
		cout << "mylambdathread start..." << endl;
		cout << "mylambdathread end..." << endl;
	};
	thread mythread(mylambdathread);
	std::cout << "Hello World1 end!\n";
	std::cout << "Hello World2 end!\n";
	std::cout << "Hello World3 end!\n";
	std::cout << "Hello World4 end!\n";
	mythread.join();
	std::cout << "Hello World5 end!\n";
	std::cout << "Hello World6 end!\n";
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值