C++新特性27_线程thread的使用(重点看C++11对线程的封装使用、线程标准库、多线程的核心:回调函数创建新的线程并作为线程的起点、 windows下经典的线程的写法、C++11对线程的封装)

本文介绍了C++11中新增的线程与同步标准库,涵盖了线程概念、多线程核心、Windows下的线程写法以及C++11对线程的封装等内容。

本篇介绍新的篇章,主要介绍线程与同步的知识。
早期C++是没有考虑多线程的,随着语言的发展,C++中增加了线程与同步的相关标准库。
总结: C++中对线程进行了封装创建新的线程,使用回调函数作为新的线程下的起点

1. C++11为多线程进行的标准库扩充

为了实现在不同系统下的多线程及同步功能,C++标准库进行了如下的扩充:这是一种语言级别的线程支持

  • std::thread
  • std::mutex/std::unique_lock
  • std::future/std::packaged_task
  • std::condition_variable

2. 线程的概念及应用

线程:进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。
(1)线程内核对象。操作系统用它来管理线程,存放线程统计信息。
(2)线程堆栈,用于维护线程在执行代码时,需要的所有函数参数和局部变量。
下图做了解
在这里插入图片描述
通俗点:
举个例子:人在吃饭的时候可能心不在焉,同时玩手机、聊天或者与好几个人聊天,这个过程我们感觉同时做了好几件事
计算机也是类似的,可以一边玩游戏,一边听音乐,但是早期的CPU是单核的(某一瞬间只能执行某一条指令),按道理不可以同时支持做好几件事,但是实际上是可以实现的,那如何实现的呢?那是因为我们把CPU划分为很多的“时间片”

什么是时间片呢?
时间片:某一间A教室(1班,2班),那如何实现一天让1班,2班都在A教室上班?
方法: 把时间划分,划分成上午(1班)和下午(2班)。

那电脑是如何实现的呢?也是类似的:
cpu(听歌代码,游戏代码),把cpu时间划分,划分为片段20ms,由线程1(听歌)和线程2(游戏代码)交替运行。这时候我们就有种错觉,我们同时在听歌和玩游戏
我们把CPU所占用的时间称之为时间片,听歌和游戏称之为线程1和线程2,这也会带来我们调试时的一些问题,但是优势大于问题。

3.多线程的核心

回调函数:一旦创建一个线程 就会以这个线程的函数作为一个新的起点,即回调函数会在新的线程中与主线程一起开始运行,这个时候我们程序就会有2个线程 主线程和子线程

4. windows下经典的线程写法

(1)利用windows下的API进行多线程的经典实现方法如下:

#include <iostream>
#include <windows.h>
#include <tchar.h>

using namespace std;

//子线程的回调函数
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
	std::cout << "hello world" << std::endl;

	return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//使用的是windows下的API
	DWORD dwThreadID = 0;
	//创建一个子线程
	HANDLE hThread = CreateThread(
		NULL,
		0,//默认栈大小

		//线程的回调函数 一旦创建一个线程 就会以这个线程的函数作为一个新的起点
		//这个时候我们程序就会同时有2个线程 主线程和子线程,看起来是同时运行
		ThreadProc,//线程回调函数 函数指针
		NULL,//参数
		0,//或者CREATE_SUSPENDED  表示是否暂停
		&dwThreadID //线程
	);

	//等待某一个信号量被触发 
	//主线程运行完后会退出 但是子线程可能没有运行完 主线程会使用下边的函数等待子线程一起退出
	//INFINITE代表等待无限时间
	WaitForSingleObject(hThread, INFINITE); 

	return 0;
}

(2)设置断点如下:
在这里插入图片描述
主线程按步运行至WaitForSingleObject(hThread, INFINITE)卡死等待子线程运行完成;
ThreadProc之后,程序会自动跳转至子线程的回调函数中,主线程等待子线程运行完一起退出
(3)查看2个线程当前运行位置
主线程运行位置,卡死等待子线程运行完成
在这里插入图片描述
子线程运行位置
在这里插入图片描述
F5之后,程序运行到最后return 0;位置,然后主线程和子线程一起退出
在这里插入图片描述
但是这样做很麻烦,不同的系统对于多线程的写法都不一样,上面的代码在linux系统下又是一种新的形式,我们需要在语言上进行统一,在语言层次提供了封装。

5. C++11对线程的封装

C++11中提供了封装,其经典写法如下:

#include <tchar.h>
#include <iostream>
#include <thread>

using namespace std;

void foo() {
	std::cout << "hello world" << std::endl;
}
//c++11 标准写法
int _tmain(int argc, _TCHAR* argv[])
{
	//创建了线程对象 核心的回调函数 这里回调函数为foo()
	std::thread t(foo);
	//主线程在等待子线程的结束
	t.join();

	return 0;
}

在这里插入图片描述
运行跳转至子线程的回调函数
在这里插入图片描述
另外一种写法,将回调函数写为Lambda表达式(匿名函数):

int _tmain(int argc, _TCHAR* argv[])
{
	//创建了线程对象 核心的回调函数 这里回调函数为foo()
	std::thread t([] {
		std::cout << "hello world" << std::endl;
	});
	//主线程在等待子线程的结束
	t.join();
	
	return 0;
}

6.学习视频地址:C++新特性27_线程thread的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值