Go 入门指南(The way to Go)用(测试数据)表驱动测试 13.10 性能调试:分析并优化 Go 程序 第 14 章 协程(goroutine)与通道(channel) 14.1 什么是协程 14.2 协程间的信道 14.3 协程的同步:关闭通道-测试阻塞的通道 14.4 使用 select 切换协程 14.5 通道、超时和计时器(Ticker) 14.6 协程和恢复(recover) 14.7 新旧模型对比:任务和worker 好地利用大量的分布式和多核的计算机, 这一点对于谷歌内部的使用来说就非常重要了。设计者通过 goroutine 这种轻量级线程的概念来实现这个目标,然 后通过 channel 来实现各个 goroutine 之间的通信。他们实现了分段栈增长和 goroutine 在线程基础上多路 复用技术的自动化。 这个特性显然是 Go 语言最强有力的部分,不仅支持了日益重要的多核与多处理器计算机,也弥补了现存编程语言在 函数中初始化。这是一类非常特殊的函数,它不能够被人为调 用,而是在每个包完成初始化后自动执行,并且执行优先级比 main 函数高。 每一个源文件都可以包含一个或多个 init 函数。初始化总是以单线程执行,并且按照包的依赖关系顺序执行。 一个可能的用途是在开始执行程序之前对数据进行检验或修复,以保证程序状态的正确性。 示例 4.6 init.go: 1. package trans 2.0 码力 | 466 页 | 4.44 MB | 1 年前3
Go 入门指南(The way to Go)好地利用大量的分布式和多 核的计算机,这一点对于谷歌内部的使用来说就非常重要了。设计者通过 goroutine 这种轻量级线程的概 念来实现这个目标,然后通过 channel 来实现各个 goroutine 之间的通信。他们实现了分段栈增长和 goroutine 在线程基础上多路复用技术的自动化。 这个特性显然是 Go 语言最强有力的部分,不仅支持了日益重要的多核与多处理器计算机,也弥补了现存 函数中初始化。这是一类非常特殊的函数,它不能够被 人为调用,而是在每个包完成初始化后自动执行,并且执行优先级比 main 函数高。 每一个源文件都可以包含且只包含一个 init 函数。初始化总是以单线程执行,并且按照包的依赖关系顺序 执行。 一个可能的用途是在开始执行程序之前对数据进行检验或修复,以保证程序状态的正确性。 示例 4.6 init.go: package trans import 在一些复杂的程序中,通常通过不同线程执行不同应用来实现程序的并发。当不同线程要使用同一个变量 时,经常会出现一个问题:无法预知变量被不同线程修改的顺序!(这通常被称为资源竞争,指不同线程对同 一变量使用的竞争)显然这无法让人容忍,那我们该如何解决这个问题呢? Go入门指南 - 169 - 本文档使用 看云 构建 经典的做法是一次只能让一个线程对共享变量进行操作。当变量被一个线程改变时(临界区),我们为它上0 码力 | 380 页 | 2.97 MB | 1 年前3
IPC性能极致优化方案-RPAL落地实践github 地址:https://github.com/cloudwego/shmipc-go 方案诞生的背景 方案诞生的背景 IPC 的性能瓶颈有哪些: 1. 系统特权级切换; 2. 异步线程唤醒/休眠(事件通知); 3. 数据拷贝(序列化/反序列化); 方案诞生的背景 能不能把库函数调用的高性能优势做到 IPC 里面,降低进程间的事件通知和数据拷贝开销? 以go-go微服务 RPC Process As Library) 方案,基于跨进程虚拟地址 共享,复用 epoll 网络模型,实现了纯用户态的事件轮询和无拷贝的指针读写接口。 从性能瓶颈的两点分析: 1. 异步线程唤醒: 关键在于如何最低限度降低线程唤醒的开销,非必要不通知事件。 2. 数据序列化/反序列化 需要做到跨进程的虚拟地址空间共享,通过传递指针来传递一切数据。 全进程地址空间共享与保护 第二部分 全进程地址空间共享与保护 个域,从而可以给每一个域单独赋予一个权限; 2. Intel x86 为每个线程提供了一个寄存器 PKRU (User Page Key Register),其长度为 32 bits,每 2-bit 对应页表中的一个 Protection Key,分别为 WD 位和 AD 位,用于控制所在域的内存访问权限。 用户态进程切换 第三部分 用户态进程切换 传统线程切换 rpal线程切换: 用户态进程切换 用户态进程切换0 码力 | 39 页 | 2.98 MB | 1 年前3
Golang 101(Go语言101 中文版) v1.21.a为了更容易和更深刻地理解Go中的各种值 第18章:数组、切片和映射 - Go中的首要容器类型 第19章:字符串 第20章:函数 - 函数类型和函数值,以及变长参数个数函数 第21章:通道 - Go特色的并发同步方式 第22章:方法 第23章:接口 - 通过包裹不同具体类型的非接口值来实现反射和多态 第24章:类型内嵌 - 不同于继承的类型扩展方式 第25章:非类型安全指针 第26章:泛型 - 如何使用和解读组合类型 第32章:代码块和标识符作用域 目录 2 第33章:表达式估值顺序规则 第34章:值复制成本 第35章:边界检查消除 并发编程 第36章:并发同步概述 第37章:通道用例大全 第38章:如何优雅地关闭通道 第39章:其它并发同步技术 - 如何使用sync标准库包 第40章:原子操作 - 如何使用sync/atomic标准库包 第41章:Go中的内存顺序保证 第42章:一些常见并发编程错误 Go有很多特性,有一些是独特的,有一些借鉴于一些其它编程语言: 内置并发编程支持: 使用协程(goroutine)做为基本的计算单元。轻松地创建协程。 使用通道(channel)来实现协程间的同步和通信。 内置了映射(map)和切片(slice)类型。 支持多态(polymorphism)。 使用接口(interface)来实现裝盒(value boxing)和反射 (reflection)。0 码力 | 591 页 | 21.40 MB | 1 年前3
Golang 101(Go语言101 中文版) v1.21.a为了更容易和更深刻地理解Go中的各种值 第18章:数组、切片和映射 - Go中的首要容器类型 第19章:字符串 第20章:函数 - 函数类型和函数值,以及变长参数个数函数 第21章:通道 - Go特色的并发同步方式 第22章:方法 第23章:接口 - 通过包裹不同具体类型的非接口值来实现反射和多态 第24章:类型内嵌 - 不同于继承的类型扩展方式 第25章:非类型安全指针 第26章:泛型 - 如何使用和解读组合类型 也解释了什么是“函数退出阶段” 第32章:代码块和标识符作用域 第33章:表达式估值顺序规则 第34章:值复制成本 第35章:边界检查消除 并发编程 第36章:并发同步概述 第37章:通道用例大全 第38章:如何优雅地关闭通道 第39章:其它并发同步技术 - 如何使用sync标准库包 第40章:原子操作 - 如何使用sync/atomic标准库包 第41章:Go中的内存顺序保证 第42章:一些常见并发编程错误 Go有很多特性,有一些是独特的,有一些借鉴于一些其它编程语言: 内置并发编程支持: 使用协程(goroutine)做为基本的计算单元。轻松地创建协程。 使用通道(channel)来实现协程间的同步和通信。 内置了映射(map)和切片(slice)类型。 支持多态(polymorphism)。 使用接口(interface)来实现裝盒(value boxing)和反射(reflection)。0 码力 | 821 页 | 956.82 KB | 1 年前3
Golang 101(Go语言101 中文版) v1.21.a为了更容易和更深刻地理解Go中的各种值 第18章:数组、切片和映射 - Go中的首要容器类型 第19章:字符串 第20章:函数 - 函数类型和函数值,以及变长参数个数函数 第21章:通道 - Go特色的并发同步方式 第22章:方法 第23章:接口 - 通过包裹不同具体类型的非接口值来实现反射和多态 第24章:类型内嵌 - 不同于继承的类型扩展方式 第25章:非类型安全指针 第26章:泛型 - 如何使用和解读组合类型 也解释了什么是“函数退出阶段” 第32章:代码块和标识符作用域 第33章:表达式估值顺序规则 第34章:值复制成本 第35章:边界检查消除 并发编程 第36章:并发同步概述 第37章:通道用例大全 第38章:如何优雅地关闭通道 第39章:其它并发同步技术 - 如何使用sync标准库包 第40章:原子操作 - 如何使用sync/atomic标准库包 第41章:Go中的内存顺序保证 第42章:一些常见并发编程错误 Go有很多特性,有一些是独特的,有一些借鉴于一些其它编程语言: 内置并发编程支持: 使用协程(goroutine)做为基本的计算单元。轻松地创建协程。 使用通道(channel)来实现协程间的同步和通信。 内置了映射(map)和切片(slice)类型。 支持多态(polymorphism)。 使用接口(interface)来实现裝盒(value boxing)和反射(reflection)。0 码力 | 608 页 | 1.08 MB | 1 年前3
Go基础语法宝典ValueOf(&x) v := p.Elem() v.SetFloat(7.1) goroutine 是 Go 并行设计的核心。 goroutine 说到底其实就是协程,但是它比线程更小,十几个 goroutine 可能体现在底层就是五六个线程,Go语言内部实现了这些 goroutine 之间的内存共享。执 行 goroutine 只需极少的栈内存(大概是4~5KB),当然会根据相应的数据伸缩。也正因为如此,可同时 此,可同时 运行成千上万个并发任务。 goroutine 比 thread 更易用、更高效、更轻便。 goroutine 是通过Go的 runtime 管理的一个线程管理器。 goroutine 通过 go 关键字实现了,其实就 是一个普通的函数。 通过关键字go就启动了一个 goroutine 。来看一个例子 可以看到go关键字很方便的就实现了并发编程。 上面的多个 goroutine 默认情况下,在Go 1.5将标识并发系统线程个数的 runtime.GOMAXPROCS 的初始值由1改为了 运行环境的 CPU核数 。 但在Go 1.5以前调度器仅使用单线程,也就是说只实现了并发。想要发挥多核处理器的并行,需要程序 中显式调用 runtime.GOMAXPROCS(n) 告诉调度器同时使用多个线程。 GOMAXPROCS 设置了同时运行逻 辑代码的系统线程的最大数量,并返回之前的设置。如果0 码力 | 47 页 | 1020.34 KB | 1 年前3
Go Web编程gofmt自动格式化支持 其他特征 支持多国语言界面显示 完全插件体系结构 支持编辑器配色方案 基于Kate的语法显示支持 基于全文的单词自动完成 支持键盘快捷键绑定方案 Markdown文档编辑支持 实时预览和同步显示 自定义CSS显示 可导出HTML和PDF文档 批量转换/合并为HTML/PDF文档 LiteIDE安装配置 LiteIDE安装配置 LiteIDE安装 下载地址 http://code 设计,而GO从语言 层面就支持了并行。 goroutine goroutine goroutine是Go并行设计的核心。goroutine说到底其实就是线程,但是他比线程更小,十几个goroutine可能体现在 底层就是五六个线程,Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大 概是4~5KB),当然会根据相应的数据伸缩。也正因为如此 ,可同时运行成千上万个并发任务。goroutine比thread更 易用、更高效、更轻便。 goroutine是通过Go的runtime管理的一个线程管理器。goroutine通过go关键字实现了,其实就是一个普通的函数。 go hello(a, b, c) 通过关键字go就启动了一个goroutine。我们来看一个例子 package main import ( "fmt"0 码力 | 295 页 | 5.91 MB | 1 年前3
Go性能优化概览-曹春晖那也⼀定要有能通过配置开启的能⼒ CPU ⽤爆了?90%? 内存⽤爆了?OOM? Goroutine ⽤爆了?80w? 线程数爆了? 延迟太⾼? 压测时关注哪些服务指标 压测时关注哪些服务指标 因为我们是 Go 的服务,还可以额外看看: • Goroutine 数,线程数 • 如果 Goroutine 数很多,那这些 Goroutine 在⼲什么? • GC 频率,gctrace 的内容(线上保存 缩⼩临界区:只锁必须锁的对象,临界区内尽量不放慢操作,如 syscall • 降低锁粒度:全局锁 -> 对象锁,全局锁 -> 连接锁,连接锁 -> 请求锁,⽂ 件锁 -> 多个⽂件各种锁 • 同步改异步:如同步⽇志 -> 异步⽇志,若队列满则丢弃,不阻塞业务逻辑 CPU 使⽤太⾼了-编解码使⽤ CPU 过⾼ 通过更换 json 库,就可以提⾼系统的吞吐量 本质上就是请求的 CPU 使⽤被优化了 lock • Global lock -> connection level lock • Connection level lock -> request level lock • 同步改异步 • ⽇志场景:同步⽇志 -> 异步⽇志 • Metrics 上报场景:select -> select+default • 个别场景使⽤双 buffer 完全消灭阻塞 Continuous Profiling0 码力 | 40 页 | 8.69 MB | 1 年前3
5.cgo 原理解析及优化实践来源:https://learnku.com/articles/41728 OS 线程 GMP 环境 执行 Go 函数 两个调用方向 C 调用 Go Go 调用 C 1 2 C 线程中调用 Go 函数 GMP 从哪里来? Go 函数导致 Goroutine 挂起会怎样? Golang 线程中调用 C 函数 C 函数长期阻塞运行会怎样? C 调 Go Extra 队列,等待调度 C 线程被挂起 ② G 被调度到 P 上执行 ③ P 让出给 C 线程 因为 G 绑定了 M C 线程恢复执行 C 调 Go – Go 需要挂 起 ① 让出 P 给其他 M C 线程被挂起 因为 G 绑定了 M ② P 让出给 C 线程 因为 G 绑定了 M C 线程恢复执行 因为 C 调用 Go 是同步 API 新建普通协程 ① lockedg 尽量少干活,尽快启动一个新的协程 newg,然后返回到 C ② 释放的 P,会携带新建的 newg,在一个新的 Go 线程上执行 Go 调 C ① “释放”P 并没有立即执行,需要等 sysmon 来 retake 属于优化;通常 C 很快返回 ② 获取不到 P,也会将 G 放入全局 G 队列 CPU 优化 第四部分 发现过程 needm:获取 extra0 码力 | 45 页 | 5.74 MB | 1 年前3
共 44 条
- 1
- 2
- 3
- 4
- 5













