当前位置: 首页 > news >正文

golang defer实现

derfer : 延迟调用,函数结束返回时执行,多个defer按照先进后出的顺序调用

原理:底层通过链表实现,每次新增的defer调用,通过头插法插入链表;defer执行时,从链表头开始遍历,相当于实现了后加入的defer先执行,先加的defer后执行

defer结构体

type _defer struct {started boolheap    bool// openDefer indicates that this _defer is for a frame with open-coded// defers. We have only one defer record for the entire frame (which may// currently have 0, 1, or more defers active).openDefer boolsp        uintptr // sp at time of deferpc        uintptr // pc at time of deferfn        func()  // can be nil for open-coded defers_panic    *_panic // panic that is running deferlink      *_defer // next defer on G; can point to either heap or stack!// If openDefer is true, the fields below record values about the stack// frame and associated function that has the open-coded defer(s). sp// above will be the sp for the frame, and pc will be address of the// deferreturn call in the function.fd   unsafe.Pointer // funcdata for the function associated with the framevarp uintptr        // value of varp for the stack frame// framepc is the current pc associated with the stack frame. Together,// with sp above (which is the sp associated with the stack frame),// framepc/sp can be used as pc/sp pair to continue a stack trace via// gentraceback().framepc uintptr
}

defer初始化

// Create a new deferred function fn, which has no arguments and results.
// The compiler turns a defer statement into a call to this.
func deferproc(fn func()) {gp := getg()if gp.m.curg != gp {// go code on the system stack can't deferthrow("defer on system stack")}d := newdefer()if d._panic != nil {throw("deferproc: d.panic != nil after newdefer")}// 这里使用头插法 插入链表d.link = gp._defergp._defer = dd.fn = fnd.pc = getcallerpc()// We must not be preempted between calling getcallersp and// storing it to d.sp because getcallersp's result is a// uintptr stack pointer.d.sp = getcallersp()// deferproc returns 0 normally.// a deferred func that stops a panic// makes the deferproc return 1.// the code the compiler generates always// checks the return value and jumps to the// end of the function if deferproc returns != 0.return0()// No code can go here - the C return register has// been set and must not be clobbered.
}

defer执行

func deferreturn() {gp := getg()for {d := gp._deferif d == nil {return}sp := getcallersp()if d.sp != sp {return}if d.openDefer {done := runOpenDeferFrame(gp, d)if !done {throw("unfinished open-coded defers in deferreturn")}gp._defer = d.linkfreedefer(d)// If this frame uses open defers, then this// must be the only defer record for the// frame, so we can just return.return}fn := d.fnd.fn = nil// 指向下一个defer节点gp._defer = d.linkfreedefer(d)fn()}
}

相关文章:

golang defer实现

derfer : 延迟调用,函数结束返回时执行,多个defer按照先进后出的顺序调用 原理:底层通过链表实现,每次新增的defer调用,通过头插法插入链表;defer执行时,从链表头开始遍历,相当于实…...

数据仓库实践

什么是数据仓库? 数据仓库是一个用于存储大量数据并支持数据分析与报告的系统。它通常用于集成来自不同来源的数据,提供一个统一的视图,以便进行更深入的分析和决策。 数据仓库的主要优势? 决策支持:为企业决策提供可靠…...

深入浅出 -- 系统架构之微服务标准组件及职责

我们来认识一下微服务架构在Java体系中依托哪些组件实现的。 相对于单体架构的简单粗暴,微服务的核心是将应用打散,形成多个独立提供的微服务,虽然从管理与逻辑上更符合业务需要。但微服务架构也带来了很多急需解决的核心问题: 1…...

IP协议中的四大支柱:DHCP、NAT、ICMP和IGMP的功能剖析

DHCP动态获取 IP 地址 我们的电脑通常都是通过 DHCP 动态获取 IP 地址,大大省去了配 IP 信息繁琐的过程。 客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的…...

基于Socket简单的UDP网络程序

⭐小白苦学IT的博客主页 ⭐初学者必看:Linux操作系统入门 ⭐代码仓库:Linux代码仓库 ❤关注我一起讨论和学习Linux系统 1.前言 网络编程前言 网络编程是连接数字世界的桥梁,它让计算机之间能够交流信息,为我们的生活和工作带来便利…...

计算机思维

计算机思维是一种运用计算机科学的基础概念和方法来解决问题、设计系统和理解人类行为的思维方式。它包括以下几个方面: 1. 抽象和建模:将复杂的现实问题抽象为计算机可以处理的模型,通过定义对象、属性和关系来构建问题的逻辑结构。 2. 算法…...

如何判断一个linux机器是物理机还是虚拟机

https://blog.csdn.net/qq_32262243/article/details/132571117 第一种方式:dmesg命令 [rootnshqae01adm03 ~]# dmesg | grep -i hypervisor [ 0.000000] Hypervisor detected: Xen PV [ 1.115297] VPMU disabled by hypervisor. 在我的机器上 dmesg也是能够用来判…...

python用requests的post提交data数据以及json和字典的转换

环境:python3.8.10 python使用requests的post提交数据的时候,代码写法跟抓包的headers里面的Content-Type有关系。 (一)记录Content-Type: application/x-www-form-urlencoded的写法。 import requestsurlhttps://xxx.comheade…...

【Datax分库分表导数解决方法】MySQL_to_Hive

Datax-MySQL_to_Hive-分库分表-数据同步工具 简介: 本文档介绍了一个基于Python编写的工具,用于实现分库分表数据同步的功能。该工具利用了DataX作为数据同步的引擎,并通过Python动态生成配置文件,并调用DataX来执行数据同步任务…...

Vue2 —— 学习(一)

目录 一、了解 Vue (一)介绍 (二)Vue 特点 (三)Vue 网站 1.学习: 2.生态系统: 3.团队 二、搭建 Vue 开发环境 (一)安装与引入 Vue 1.直接引入 2.N…...

Windows Server 2008添加Web服务器(IIS)、WebDAV服务、网络负载均衡

一、Windows Server 2008添加Web服务器(IIS) (1)添加角色,搭建web服务器(IIS) (2)添加网站,关闭默认网页,添加默认文档 在客户端浏览器输入服务器…...

SpringMVC转发和重定向

转发和重定向 1. View Resolver Spring MVC 中的视图解析器&#xff08;View Resolver&#xff09;负责解析视图。可以通过在配置文件中定义一个 View Resolver 来配置视图解析器&#xff1a; 配置文件版&#xff1a;spring-web.xml <!-- for jsp --> <bean class&q…...

勒索病毒最新变种.rmallox勒索病毒来袭,如何恢复受感染的数据?

导言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络安全问题日益突出&#xff0c;其中勒索病毒便是近年来备受关注的网络安全威胁之一。在众多勒索病毒中&#xff0c;.rmallox勒索病毒以其独特的传播方式和强大的加密能力&#xff0c;给广大用户带来了极大的困扰。本文…...

复试专业课问题

1、数据结构&#xff1a;详细描述归并排序的过程 归并排序是用分治思想&#xff0c;分治模式在每一层递归上有三个步骤&#xff1a; 分解&#xff08;Divide&#xff09;&#xff1a;将n个元素分成个含n/2个元素的子序列。解决&#xff08;Conquer&#xff09;&#xff1a;用…...

比特币革命:刚刚开始

作者&#xff1a;Marius Farashi Tasooji 编译&#xff1a;秦晋 要充分理解比特币及其含义&#xff0c;首先必须理解什么是价值&#xff0c;什么是货币。以及是什么赋予资产价值&#xff1f; 这个问题看似愚蠢&#xff0c;但实际上非常有趣。我们的生活是由我们消费或出售的物品…...

淘宝店商家电话提取软件操作经验

淘宝爬虫工具是一种用于自动化获取淘宝网站数据的程序。以下是一个简单的淘宝爬虫工具的代码示例&#xff1a; import requests from bs4 import BeautifulSoupdef get_taobao_data(keyword):url fhttps://s.taobao.com/search?q{keyword}headers {User-Agent: Mozilla/5.0…...

【进阶六】Python实现SDVRPTW常见求解算法——遗传算法(GA)

基于python语言&#xff0c;采用经典蚁群算法&#xff08;ACO&#xff09;对 带硬时间窗的需求拆分车辆路径规划问题&#xff08;SDVRPTW&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整2.1 需求拆分2.2 需求拆分后的服务时长取值问题 3. 求解结果4. 代码片段…...

【Android】App通信基础架构相关类源码解析

应用通信基础架构相关类源码解析 这里主要对Android App开发时&#xff0c;常用到的一些通信基础类进行一下源码的简单分析&#xff0c;包括&#xff1a; Handler&#xff1a;处理器&#xff0c;与某个Looper&#xff08;一个线程对应一个Looper&#xff09;进行关联。用于接…...

06-kafka配置

生产者配置 NAMEDESCRIPTIONTYPEDEFAULTVALID VALUESIMPORTANCEbootstrap.servershost/port列表&#xff0c;用于初始化建立和Kafka集群的连接。列表格式为host1:port1,host2:port2,…&#xff0c;无需添加所有的集群地址&#xff0c;kafka会根据提供的地址发现其他的地址&…...

Git、TortoiseGit、SVN、TortoiseSVN 的关系和区别

Git、TortoiseGit、SVN、TortoiseSVN 的关系和区别 &#xff08;一&#xff09;Git&#xff08;分布式版本控制系统&#xff09;:&#xff08;二&#xff09;SVN&#xff08;集中式版本控制系统&#xff09;&#xff08;三&#xff09;TortoiseGit一、下载安装 git二、安装过程…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...