8、Swift协程详解:TaskLocal

TaskLocal 值的定义和使用

TaskLocal 值就是 Task 私有的值,不同的 Task 对于这个变量的访问将得到不同的结果。

下面我们给出示例演示如何定义一个 TaskLocal 值:

TaskLocal 值必须定义为静态的存储属性,并使用 TaskLocal 这个属性包装器(property wrapper)来包装。TaskLocal 值也受限于属性包装器的支持范围,不能定义为顶级属性。

变量 tag 的初始值为 default,属性包装器 TaskLocal 的构造器会接收这个值并存起来备用:

了解属性包装器的读者应该也能想到初始值的定义还可以写:

通过观察 TaskLocal 的定义,我们也发现它对于被包装的类型是有要求的,即要实现 Sendable 协议。

了解了定义之后,接下来看用法。

首先要写入值,我们只需要调用属性包装器的 withValue 函数,它的声明如下:

调用示例如下:

其中 $tag 就是 tag 的属性包装器的 projectedValue,这个值正是 TaskLocal 这个属性包装器对象本身。

withValue 有两个参数,一个是要绑定给 tag 的值,即 MyTask;另一个就是一个闭包,这个绑定的值只有在这个闭包当中有效,一旦闭包执行结束,tag 绑定的值的生命周期也就结束了。

接下来我们尝试去读取它:

读取的方式就显得普通而又枯燥了。写法非常直接,不过大家要明白,这个读的行为实际上是通过 TaskLocal 属性包装器完成的。

作为对比,我们给出一个稍微完整的例子:

运行结果如下:

Task 对于 TaskLocal 的继承

上一篇文章当中我们通过示例演示了 initdetach 构造的 Task 实例对 actor 上下文的继承,这次我们给大家再演示一下对 TaskLocal 的继承,以进一步加深大家的理解:

这个例子相比之前的调度器的例子就更显得普通而又枯燥了,程序输出如下:

可以看到,通过 detached 创建的 Task 实例可谓是”六亲不认”,不仅不继承 actor 的上下文,也对 TaskLocal 不管不顾。另外不难想到的是,Swift 并没有提供修改外部 TaskLocal 值的 API,因此外部的 TaskLocal 值只能被继承,不能被修改。

深入探查 TaskLocal 的存储方式

TaskLocal 值虽然看起来就是个静态存储属性,但它的值实际上是存储在 Task 相关的内存当中的。它的读写性能自然也与它的存储方式有关,因此为了确保能够正确合理的使用 TaskLocal,我们有必要了解一下它究竟是如何存储的。

这时候我们注意到有几个关键的函数,它们的定义如下:

通过 _silgen_name 的值,我们可以找到他们在 C++ 当中的定义,以 _taskLocalValueGet 为例,我们给出 swift_task_localValueGet 的代码:

AsyncTask::localValueGet 本质上调用的就是 TaskLocal::Storage::getValue(AsyncTask *,const HeapObject *),我们同样可以找到它的实现:

可见,查找过程其实就是链表的遍历查找,时间复杂度为 O(n)。

我们再稍微观察一下插入和删除的代码:

不难发现这实际上就是一个采用头插法的单链表。为什么选择这样的设计呢?

显然,绝大多数情况下 TaskLocal 值的数量都不会很多,同时插入的值只在 withValue 函数范围内有效也使得绝大多数查找的值都排在链表前面,因此线性查找的效率并不会存在性能问题。

而链表的结构也使得增删节点非常容易,使用头插法使得 withValue 函数退出时释放销毁对应的值也变得非常容易,时间复杂度只需要 O(1)。

另外,使用单链表来存储 TaskLocal 值还有一个好处,那就是变量遮蔽,例如:

运行结果如下:

简单总结一下,TaskLocal 值是存在链表当中的,我们在使用过程中应当避免使用过多的 TaskLocal 值,也应该适当地减少对 TaskLocal 值的访问次数,以避免性能上最坏的情况出现。

本文我们对 TaskLocal 值的使用和实现机制做了剖析。

Original: https://www.cnblogs.com/strengthen/p/16243570.html
Author: 山青咏芝
Title: 8、Swift协程详解:TaskLocal

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/553573/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • ES基本查询语句教程

    前言 es是什么? es是基于Apache Lucene的开源分布式(全文)搜索引擎,,提供简单的RESTful API来隐藏Lucene的复杂性。 es除了全文搜索引擎之外,还可…

    技术杂谈 2023年6月1日
    099
  • Java日志框架

    流行的日志框架 JUL Log4j JCL SLF4j Logback Log4j2 总结 依赖导入总结 日志门面 日志实现 桥接器、适配器理解 使用logback + slf4j…

    技术杂谈 2023年7月11日
    076
  • 让图片垂直居中

    在不同的编码模式下,文字的行高计算是不一样的,所以请记住选择与页面相对的编码 这种方法是利用 display:table-cell在支持该属性的浏览器中,结合 _vertial-a…

    技术杂谈 2023年5月31日
    075
  • npm命令大全

    https://blog.csdn.net/qq575792372/article/details/122150069 NPM 的全称是 Node Package Manager,…

    技术杂谈 2023年6月1日
    072
  • 跨境电商独立站怎么做

    独立站一般是指商家自己搭建的跨境电商网站。跨境电商独立站拥有独立域名,内容、数据、权益私有,脱离第三方电商平台束缚,不仅可以进行多个渠道、多个方式的网络曝光和推广,并且推广所带来的…

    技术杂谈 2023年5月31日
    090
  • Mall商城的高级篇的开发(二)性能压测和性能监控

    Mall商城的高级篇的开发(二) 性能压测–压力测试 压力测试考察当前软件硬件环境下系统所能承受的最大负荷并帮助找出系统的瓶颈所在。压测都是为了系统在上线的处理能力和稳…

    技术杂谈 2023年7月11日
    076
  • dubbo源码阅读

    http://seekheap.com/posts/dubbo/dubbo-src-01-overview-and-debug-environment.html 先占坑 Origi…

    技术杂谈 2023年6月1日
    062
  • Chrome Service Model

    John Abd-El-Malek February 2016 Objective Move Chrome codebase towards a service-oriented …

    技术杂谈 2023年5月31日
    0106
  • Win10系统的SurfacePro4无法修改启动顺序怎么办

    必须要把底部的开关关闭,否则启动顺序无法修改 本文为博主原创文章,未经博主允许不得转载。 posted @2018-08-20 22:37 gary_tao 阅读(1850 ) 评…

    技术杂谈 2023年5月31日
    0258
  • 蓝牙搜索

    /******************************************************************** created: 2010/01/29 …

    技术杂谈 2023年5月31日
    088
  • elasticsearch

    一、什么是Elasticsearch? Lucene是一套用于 全文检索和 搜寻的 开源程序库,由Apache软件基金会支持和提供 Lucene提供了一个简单却强大的应用程序接口(…

    技术杂谈 2023年7月10日
    039
  • join连接的五种方式的简单使用案例(Inner join,Left join,Right join,Full join,Cross join)

    1.内连接Inner join内连接是基于连接谓词将俩张表(如A和B)的列组合到一起产生新的结果表,在表中存在至少一个匹配时,INNER JOIN 关键字返回行。 下面是一个简单的…

    技术杂谈 2023年6月1日
    063
  • FineUIPro/Mvc/Core v7.1.0 正式发布了!

    FineUIPro/Mvc/Core v7.1.0 正式发布了,这个版本支持了多文件上传,WebForms版修正了一个通杀.Net Framework的XSS漏洞,基础版也第一次支…

    技术杂谈 2023年6月1日
    076
  • HTTP协议

    请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。 Accept Accept请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:image/gif …

    技术杂谈 2023年7月24日
    066
  • 方位

    【 方位】 1、《3D数学基础》中,方位被称为 head(y轴)、pitch(x轴)、bank(z轴)。但书上提到 head==yaw,bank==roll。 2、《Real-Ti…

    技术杂谈 2023年5月31日
    068
  • 汇编实验二设置栈顶

    实验笔记二:ss设置栈顶 mov ax,2000 mov ss,ax mov sp,0010 mov ax,2000 mov ss,ax mov sp,0010 执行后,内存地址会…

    技术杂谈 2023年6月21日
    058
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球