| |
|
开发:
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++ 标准库之移交线程归属权解析 |
前景知识理解线程归属权的移交方法,需要了解std::move(右值转换)和std::forward(完美转发)相关知识,先介绍三个规则。 规则1(引用折叠规则):如果间接的创建一个引用的引用,则这些引用就会“折叠”。在所有情况下(除了一个例外),引用折叠成一个普通的左值引用类型。一种特殊情况下,引用会折叠成右值引用,即右值引用的右值引用, T&& &&。即
规则2(右值引用的特殊类型推断规则):当将一个左值传递给一个参数是右值引用的函数,且此右值引用指向模板类型参数(T&&)时,编译器推断模板参数类型为实参的左值引用,如:
上述的模板参数类型T将推断为int&类型,而非int。若将规则1和规则2结合起来,则意味着可以传递一个左值 规则3(static_cast转换):虽然不能隐式的将一个左值转换为右值引用,但是可以通过static_cast显示地将一个左值转换为一个右值。【C++11中为static_cast新增的转换功能】。标准库中move的定义如下:
move函数的参数T&&是一个指向模板类型参数的右值引用【规则2】,通过引用折叠,此参数可以和任何类型的实参匹配(传递左值时,折叠成T&,传递右值时折叠成T&&),因此move既可以传递一个左值,也可以传递一个右值。从move的定义可以看出,move自身除了做一些参数的推断之外,返回右值引用本质上还是靠static_cast<T&&>完成的。注意,std::move返回的永远是右值引用。
std::forward<T>()不仅可以保持左值或者右值不变,同时还可以保持const、lreference、rreference、validate等属性不变。 移交线程归属权何为移交线程归属权?假设编写一个函数,功能是创建线程,并置于后台运行,但该函数本身不等待线程完结,而是将其归属权向上移交给函数的调用者;或相反地,读者想创建线程,遂将其归属权传入某个函数,由它负责等待该线程结束。两种操作都需要转移线程的归属权。 std::thread支持移动语义是移交线程归属权的前提,所谓移动语义,简单来说就是资源只能移动不可以拷贝。 std::thread 移交线程归属权实例解析:
首先,我们启动新线程①,并使之关联t1。接着,构建t2,在其初始化过程中调用std::move(),将新线程的归属权显式地转移给t2[9]②。在②之前,t1关联着执行线程,some_function()函数在其上运行;及至②处,新线程关联的变换为t2。 然后,启动另一新线程③,它与一个std::thread类型的临时对象关联。新线程的归属权随即转移给t1。这里无须显式调用std::move(),因为新线程本来就由临时变量持有,而源自临时变量的移动操作会自动地隐式进行。 t3按默认方式构造④,换言之,在创建时,它并未关联任何执行线程。在⑤处,t2原本关联的线程的归属权会转移给t3,而t2是具名变量,故需再次显式调用std::move(),先将其转换为右值。经过这些转移,t1与运行some_other_function()的线程关联,t2没有关联线程,而t3与运行some_function()的线程关联。 在最后一次转移中⑥,运行some_function()的线程的归属权转移到t1,该线程最初由t1启动。但在转移之时,t1已经关联运行some_other_function()的线程。因此std::terminate()会被调用,终止整个程序。该调用在std::thread的析构函数中发生,目的是保持一致性。2.1.1节已解释过,在std::thread对象析构前,我们必须明确:是等待线程完成还是要与之分离。不然,便会导致关联的线程终结。赋值操作也有类似的原则:只要std::thread对象正管控着一个线程,就不能简单地向它赋新值,否则该线程会因此被遗弃。 std::thread支持移动操作的意义是,函数可以便捷地向外部转移线程的归属权。 一个更加完整的例子:
|
|
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年11日历 | -2024/11/24 3:07:18- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |