| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 现代C++教程笔记(下) -> 正文阅读 |
|
[C++知识库]现代C++教程笔记(下) |
文章目录前言链接: 第 6 章 正则表达式正则表达式不是 C++ 语言的一部分,给一个GitHub网站,我当时大概过了一遍: 传统上我们只能使用 boost 的正则表达式库。 而 C++11 正式将正则表达式的的处理方法纳入标准库的行列,从语言级上提供了标准的支持, 不再依赖第三方。 C++11 提供的正则表达式库操作 std::string 对象, 模式 std::regex (本质是 std::basic_regex)进行初始化, 通过 std::regex_match 进行匹配, 从而产生 std::smatch (本质是 std::match_results 对象)。 用法:
大佬的回答: 第 7 章 并行与并发额外可参考的资料https://www.bookstack.cn/books/CPP-Concurrency-In-Action-2ed-2019 以及关于并行并发我非常认同这个回答: 并发描述的是“如何处理”,而并行描述的是“如何执行”,将并发理解为一种解决问题的方法,将大的任务拆解为许许多多小的可以并发的任务是重要的编程思想。 线程支持库文档: 并行基础std::thread 用于创建一个执行的线程实例,使用时需要包含 头文件, 一些基本操作: 对于join上面链接有解释:The function returns when the thread execution has completed. 而对于detach,也有解释:Detaches the thread represented by the object from the calling thread, allowing them to execute independently from each other.After a call to this function, the thread object becomes non-joinable and can be destroyed safely. detach原本在英文中就有分离的意思,这里就是说将线程与调用它的父线程分离开而独自运行,且之后不能再join,并且可以安全的销毁。 下面我根据链接中的示例改编出一个程序,一次解释join和detach:
chrono是一个time library,和regex一样,也是源于boost,后被C++11引入标准库。上面代码就是一个暂停多少秒的函数,而同时我又用了Sleep函数(需要引入头文件Windows.h)去暂停主线程,运行结果如下: 互斥量与临界区C++11 引入了 mutex 相关的类,其所有相关的函数都放在 头文件中。 通过实例化 std::mutex 可以创建互斥量, 而通过其成员函数 lock() 可以进行上锁,unlock() 可以进行解锁。 C++11 还为互斥量提供了一个 RAII 语法的模板类 std::lock_guard。 RAII 在不失代码简洁性的同时,很好的保证了代码的异常安全性。在 RAII 用法下,对于临界区的互斥量的创建只需要在作用域的开始部分。 不过在并发编程中,推荐使用 std::unique_lock 以独占所有权的方式管理 mutex 对象上的上锁和解锁的操作。unique_lock 是 相对于 lock_guard 出现的,因此它们功能有些类似但unique_lock更加灵活。 std::unique_lock对象实例化后会直接接管std::mutex。如果你用到了条件变量 std::condition_variable::wait 则必须使用 std::unique_lock 作为参数。 std::lock_guard 不能显式的调用 lock 和 unlock, 而 std::unique_lock 可以在声明后的任意位置调用, 可以缩小锁的作用范围,提供更高的并发度。 用法示例(CriticalSection就是临界区的意思,即访问共享数据的程序片段):
引入了unique_lock 、lock_guard ,我们接着就要引入adopt_lock、defer_lock、try_to_lock 先放链接: 从链接中我们看adopt_lock的解释,知道它仅仅用来消除构造函数的歧义(事实上adopt_lock、defer_lock和 try_to_lock都有写说明:The value is a compile-time constant that carries no state, and is merely used to disambiguate between constructor signatures.),啥意思呢,我们看源码(前面说了在VS2019中): 至于后二者都是用在unique_lock中而不能在lock_guard中,defer_lock初始化了一个没有lock的mutex,而try_to_lock就是尝试去lock,可以从源码的注释窥见一二: 最后再引入读写锁shared_mutex,shared_mutex通过lock_shared,unlock_shared,shared_lock进行读者的锁定与解锁;通过lock,unlock,unique_lock进行写者的锁定与解锁。 期物期物(Future)表现为 std::future,它提供了一个访问异步操作结果的途径,可以联想屏障(barrier),可以作为一种简单的线程同步手段。 参考链接:https://www.cplusplus.com/reference/future/future/?kw=future 这里我再次从原文copy一下示例代码,再简单分析:
这里std::packaged_task,可以用来封装任何可以调用的目标,从而用于实现异步的调用。在封装好要调用的目标后,可以使用 get_future() 来获得一个 std::future 对象,以便之后实施线程同步。 std::future::wait,在前面的参考链接可以看到这样的描述:If the shared state is not yet ready (i.e., the provider has not yet set its value or exception), the function blocks the calling thread and waits until it is ready. 因此这里result.wait()就是设置屏障,等待线程(期物)完成,之后可用get得到期物结果。但是其实示例代码不调用 wait() 也行,因为 std::future::get 中也有描述:If the shared state is not yet ready (i.e., the provider has not yet set its value or exception), the function blocks the calling thread and waits until it is ready. 也就是说,如果调用get的时候还没有完成期物,那么get函数此时就会阻塞调用线程,知道可以得到期物结果。 于是我修改一下示例代码来验证:
结果就是会在这里等待5秒: 条件变量条件变量 std::condition_variable 是为了解决死锁而生,当互斥操作不够用而引入的。需要#include<condition_variable>。std::condition_variable的 notify_one() 用于唤醒一个线程; notify_all() 则是通知所有线程。 原文给了一个生产者消费者模型的例子,可以查阅一下。 原子操作与内存模型在汇编层面,我们把单指令的操作称为原子的(Atomic)。在Windows中有一套API专门进行一些原子操作,这些API被称为 Interlocked API,这里放一个MSDN链接: 比如一个著名的例子,++i 代码在很多体系结构上会这样实现:
这样一句代码分为了三个指令,就不会是原子的,多线程不处理好就会出问题。 原子操作这里引入 std::atomic 模板,使得我们实例化一个原子类型,将一个 原子类型读写操作从一组指令,最小化到单个 CPU 指令。例如: 并为整数或浮点数的原子类型提供了基本的数值成员函数,举例来说, 包括 fetch_add, fetch_sub 等,同时通过重载方便的提供了对应的 +,- 版本。 我们总是可以通过 std::atomic::is_lock_free 来检查该原子类型是否需支持原子操作,毕竟不是所有的类型都能提供原子操作,原子操作的可行性取决于 CPU 的架构以及所实例化的类型结构是否满足该架构对内存对齐 条件的要求。 一致性模型并行执行的多个线程,从某种宏观层面上讨论,可以粗略的视为一种分布式系统。 在分布式系统中,任何通信乃至本地操作都需要消耗一定时间,甚至出现不可靠的通信。因此我们可以通过削弱原子操作的在进程间的同步条件来适当加速程序。 从原理上看,每个线程可以对应为一个集群节点,而线程间的通信也几乎等价于集群节点间的通信。 削弱进程间的同步条件,通常我们会考虑四种不同的一致性模型:线性一致性、顺序一致性、因果一致性、最终一致性。详细描述请看原书第七章7.5。 内存顺序为了追求极致的性能,实现各种强度要求的一致性,C++11 为原子操作定义了六种不同的内存顺序 std::memory_order 的选项,表达了四种多线程间的同步模型:宽松模型、释放/消费模型、释放/获取模型、顺序一致模型。详细描述请看原书第七章7.5。 第 8 章 文件系统文件系统库提供了文件系统、路径、常规文件、目录等等相关组件进行操作的相关功能。和正则表达式库类似,他也是最先由 boost 发起,并最终被合并为 C++ 标准的众多库之一。 这里原书还没有写,就给个链接好了: 第 9 章 其他杂项long long intC99把long long int纳入,但 C++11 才正式把它纳入标准库, 规定了一个 long long int 类型至少具备 64 位的比特数。 noexceptC++ 相比于 C 的一大优势就在于 C++ 本身就定义了一套完整的异常处理机制。且C++11 将异常的声明简化为以下两种情况:
并使用 noexcept 对这两种行为进行限制,使用 noexcept 修饰过的函数如果抛出异常,编译器会使用 std::terminate() 来立即终止程序运行。noexcept 还能够做操作符,用于操作一个表达式,当表达式无异常时,返回 true,否则返回 false。 见我的笔记第11点: noexcept 修饰完一个函数之后还能够起到封锁异常扩散的功效,如果内部产生异常,外部也不会触发。 字面量原始字符串字面量C++11 提供了原始字符串字面量的写法,可以在一个字符串前方使用 R 来修饰这个字符串, 同时,将原始字符串使用括号包裹。 比如字符串 C:\File\To\Path ,按传统需要写为:
但是我们现在可以写为:
这样就避免了大量的转义符。注意,这里的 " " 内必须要用小括号包裹。 自定义字面量C++11 引进了自定义字面量的能力,通过重载双引号后缀运算符实现,这里我也直接copy原文代码了,详细需要再看看原文:
结果是打印 内存对齐C++ 11 引入了两个新的关键字 alignof 和 alignas 来支持对内存对齐进行控制。 alignof 关键字能够获得一个与平台相关的 std::size_t 类型的值,用于查询该平台的对齐方式。alignas则是重新修饰某个结构的对齐方式。 参考链接: 示例代码:
如上,输出结果为 总结本节介绍的几个特性是从仍未介绍的现代 C++ 新特性里使用频次较靠前的特性了,noexcept 是最为重要的特性,它的一个功能在于能够阻止异常的扩散传播,有效的让编译器最大限度的优化我们的代码。 第 10 章 展望:C++20 简介这里原书也有很多还未完成的部分,期待作者大大之后补完,一共有: 先放一个参考链接:https://en.cppreference.com/w/cpp/20 概念与约束知乎上有文章: 这里原书似乎有误,应为sortable而不是Sortable,见链接: 这里我写了一段代码来测试concept:
如上,该代码是想测试一个容器可否被algorithm来sort。我是直接来看它的迭代器类型是否是random_access_iterator_tag,concept 后面需要跟一个bool型,所以我就用stl的is_same,然后用迭代器萃取机去萃取迭代器类型,看他是否和random_access_iterator_tag相等。 于是,满足concept的就会进入
这里使用了 requires sortable_container<T>,这些都属于新特性concept的使用。 顺便一提,要是我去掉:
那么在 模块给一个知乎文章吧: 结语原书还有一些没写完的内容(第八章、第十章),其他内容都很精炼,以后估计还会来看第二遍。 希望以后能看完这本书: 不过听说看英文原文更好,但不管怎样还是辛苦这些作者译者了,站在大佬们的肩膀上是一件幸福的事情。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/29 4:20:20- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |