当前课程知识点:基于Linux的C++ >  第十四讲 线程编程 >  14.9 C++11线程库(一) >  LinuxCPP1409

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP1409在线视频

LinuxCPP1409

下一节:LinuxCPP1410

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP1409课程教案、知识点、字幕

接下来一节是C++11线程库

C++11为我们提供了丰富的线程功能

也就是多线程编程的能力

在C++11以后 语言本身就提供了

它的最主要的好处

就能够支持我们平台无关的并行程序开发

它提供了五个主要的库

一个是atomic 一个是thread

一个是mutex一个是condition_variable

最后一个是future

首先是thread

这是我们的核心库 thread

它是一个线程类

提供了一个线程类——std::thread

这样的一个类

然后内部还定义了一个名空间

叫std::this_thread

这样的一个名空间

用它存了一些常用的线程管理函数

就在那个名空间里

定义了一系列的常用的线程管理函数

第二个就是mutex这个库

这个库就是互斥相关类

都在这个mutex这个库里边

包括标准的mutex这个互斥类

包括特定的互斥类

包括管理这些互斥类的几个管理类

最主要的是lock_guard

还有unique_lock

第三个是condition_variable

这是条件变量

相关的条件变量类 都放在这里

atomic是原子类

主要定义的是atomic这样的一个类

实际上是一个模板

然后是atomic_flag这样的一个类

另外还有一套C风格的

原子型和原子操作函数

那是早期的遗留

所以实际上这里面的实现

稍微有那么一点点小混乱

最后是一个future库

future库包括两个承诺类

一个是std::promise

还有一个td::packaged_task

打包任务

这两个都是承诺

相对应地就有一个期许

std::future

还有std::shared_future

这是一个共享期许

那个是标准期许

这是两个期许

你想给我一个承诺

这边就有一个期望

这是一个期许

要么怎么叫许诺呢 就这个意思

一个叫期许 一个叫承诺

我们首先来看线程类

线程类的名字就叫thread

就定义在thread这个库里

它支持的线程函数

没有参数或返回值的特别要求

就是说线程函数有没有参数都可以

有没有返回值呢都可以

要比Linux标准的那个线程函数

功能一下子就扩展了很多

那个函数必须带一个哑型指针

作为函数参数

返回值必须是哑型指针

这里都不做要求

什么函数都可以

这样的话就极大地方便了我们的编程

同时 与Linux线程机制相比

C++11这个线程类的实现

其实会简单一点

因为要支持跨平台

所以很多功能在Linux上面有

换了别的操作系统可能就没有

所以为了支持跨平台

它实现会简单一点

同时它使用上其实也更方便

线程局部存储直接使用thread_local

这个关键字定义它就完了

使用起来要比Linux那个实现方便很多

重要地 你可以派生自己的thread的类

你如果觉得标准库里面

这个thread这个类不够你用

它不满足Linux编程的要求

那你可以在此基础之上

派生自己的线程类

但是你要特别注意

在实现自己的线程类的时候

这个线程类只能支持移动语义

不能支持拷贝语义

它是不允许拷贝的

那个线程的管理是操作系统来去处理的

所以它是不支持拷贝语义的

只能移动 不能拷贝

你在实现自己线程类的时候

要特别注意这一点

常用的线程类的成员函数有这么三个

一个是看这个线程是不是处于可联状态

就是joinable() 看一下

等待这个线程结束呢 就join()

想分离这个线程呢 就detach()

就这三个函数

和Linux那三个函数是对应的

定义于名空间的这几个线程管理函数

我们经常会用到的

一个是getid() 获取线程的ID

还有一个在处于等待状态的时候

让调度器选择其它线程去调度去吧

你别管我了 就这个意思

调用yield()

还有一个阻塞当前的线程

指定的时长

用sleep_for()这样的一个函数

还有一个阻塞当前的线程

到指定的时点

你可以用下面的这个函数sleep_until()

当然这两个函数带的都是一些模板参数

时间设定的模板参数

有的是时间 有的是期限

它的设定模板参数用起来比较复杂

那几个东西都在chrono那个名空间里

都在chrono里

所以你要去看chrono那个定义

才能够去使用它

我们来看几个例子

一个是一个无参数的线程函数该怎么用

我们定义了一个线程函数ThreadFunc()

用的时候特简单

std::thread 那是那个类的名字

t 定义这个类的对象

小括号对 构造它

传什么呢 传线程函数&ThreadFunc

写不写“&”都是取它的函数入口地址

OK 搞定了我们就创建了一个线程

这个线程创建完了以后

操作系统立即就会调度它

自动调度 自动执行

线程做完了 t.join() 等它

你看我们创建了一个线程

就这么简单的两条语句

一个线程对象的定义

一个线程对象的成员函数调用

这事就做完了 简单吧

什么细节你都不用管

当然特别方便

这是无参数的线程函数

如果这个线程是需要带参数怎么办

你比如我们这里这个线程函数

ThreadFunc()将会带双参数

两个整数a和b

我要把这两个整数加在一块

简单 在定义这个线程对象的时候

传附加参数

线程对象的构造函数的参数是可变的

第一个是线程函数的入口地址

后边紧跟着的

就是你要传给那个线程函数的参数

想传几个就传几个

想传什么型 就传什么型

写在后边它就给你照抄过去

这个线程的构造函数就中转一下

就直接把它扔给了线程函数

很典型吧 想传俩参数

就在构造这个线程对象的时候

作为附加参数传进去 over

然后t.join() 等待线程结束 做完了

这就是带双参数的线程函数

就比刚才多俩参数 其它没变化

第三个 我们可以使用

带双参数的函子对象

作为构造线程时传进去的那个参数

这就比Linux线程编程灵活多了

Linux里边只能传线程函数啊

你可不能传函子对象

到了我们C++11里你可以传函子对象

没问题

你可以定义一个函子Functor

在这里边你重载了函数调用操作符

OK 没有问题

这个函数调用操作符有没有参数

随意 随便你 看你程序需要

有参数就写 没参数就不用写

然后你构造这个线程对象的时候

第一个参数就传那个Functor()

我们构造这个函子的一个匿名对象传进去

传一个函子进去 OK

它就会调用那个函子重载的

函数调用操作符

把它当做一个函数调用

然后你在构造这个线程对象的时候

传的额外这两个参数

就会作为那个线程函数的参数传进去

特方便吧 这是第三个例子

第四个例子

你还可以使用标准库里的std::bind()这个函数

绑定一个对象和它的普通的成员函数

作为我们的线程函数

这就很神奇了 你比如讲

我们这里面定义一个类class Worker

这是我们的劳工类

它专门做我们的线程执行的

里面有一个成员函数叫ThreadFunc()

具体的代码我就不写了

跟刚才是一模一样的

我们构造一个线程对象t

小括号对里面传一个参数

那个参数就是std::bind()

这个函数的返回值

它给你绑定好了以后的

那个类的成员函数

std::bind()这个函数本身

我们这里传两个参数

第一个参数就是

那个类的成员函数的入口地址

所以我们传&Worker::ThreadFunc

第二个参数你要传那个对象

所以我们传worker这个对象的基地址 &worker

把这个对象的基地址传过去

那么它就会在这个对象上

调用这个普通的成员函数

就用它作为我们的线程函数

这是Linux线程库里做不到的事情

很神奇吧

就可以做完

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP1409笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。