vs2019 cpp20 规范的线程头文件 <thread> 注释并探讨几个问题(中)

(6 探讨六) 使用库里全局函数 ref 。通过以上咱们已知道:子线程中的函数执行,即使函数形参是引用,也引用不到主线程中的实参变量。子线程中函数对形参的修改,也不会影响主线程中实参变量的值。但如果一定要在子线程中的函数里修改主线程中对应的值。就要避免传递引用和变量本身,而改为使用全局函数 std::ref() 和指向变量的指针。测试如下:

在这里插入图片描述

原因就要参考 reference_wrapper 模板类的源码:

在这里插入图片描述

因为借助 ref ,可以直接使用对象的引用,避免使用对象指针,还是更方便的。

(7 探讨七) 创建线程时传递的函数是如何在全局函数 invoke 里被调用的。传递给线程要执行的函数,可以是普通函数,可调用对象,类的成员函数(又有静态和非静态之分),对象的成员指针指向的对象的成员函数。其与 invoke 中 elseif 分支的对应关系如下:

在这里插入图片描述

这个图在上篇中出现过,但当时注释不甚精准,再修正补充一下。
时间来到了第二天,看了王老师的课以后,又对上图中的 elseif 分支,多明白了一些。补充到下图里:

在这里插入图片描述
上图中出现了 reference_wrapper 对象的 get 函数,其定义如下:

在这里插入图片描述

其成员函数也说明, reference_wrapper 类型的变量完全可以当做对象的引用来使用。相应的测试如下:

在这里插入图片描述

(8 探讨八)创建线程的第一个参数,可以是普通函数,或者可调用对象,还可以是对对象的引用:非 &obj_A 格式,这是取对象的地址,而是 std :: ref ( obj_A ) 的返回值 reference_wrapper 对象,该对象可以当成是对可调用对象的引用。测试如下:

在这里插入图片描述

因为对 全局 invoke 函数的分支执行的打印还没有删。出现了 invoke 函数的两次调用,这是为什么呢,而且为什么 reference_wrapper 对象也可以作为创建线程的第一个参数呢?图解如下:

在这里插入图片描述

(9 探讨九) join 函数的放置位置,应在主线程中靠后的位置,因为会阻塞主线程,测试如下:

在这里插入图片描述

看源码对 join 函数的定义:

在这里插入图片描述

作为反例,移动下 join 的位置,则子线程陷入了死循环,如下图,正是因为如此,才第一次发现了 join 的位置放置,也要注意,也是有大学问的:

在这里插入图片描述

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值