Go语言并发之道学习-----基本概念

本文围绕Golang并发展开,介绍了并发中竞争条件,它是因顺序性思维导致的难发现的并发bug。还阐述了原子性,其可根据上下文改变,设计时要先定义范围。此外,提到内存访问同步,数据竞争时输出可能错误,常用锁机制但会有性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

并发概述

并发:通常指的是一个或多个进程同时发生的过程
1、竞争条件:当两个或多个操作必须按正确的顺序执行,而程序并未保证顺序

var data int
go func(){
	data++
}()
if data == 0{
	fmt.Printf("The data:%d\n",data)
}

这段代码可能会有三种情况

  • 不打印
  • 打印 The data:0
  • 打印 The data:1
    因此代码中会有不确定性,这应该是被避免出现的,竞争出现的主要原因是在于顺序性的思维方式,竞争条件是最难发现的并发bug类型之一
    2、原子性
    如果被认定为是原子的或具有原子性时,意味着在运行环境中是不可分割的或不可中断的
    上下文:某个东西在此上下文中是原子性的,而在其他上下文中就不是原子性了。比如在应用程序的上下文中某操作是原子操作,而在操作系统的上下文中就不是原子性了。即操作原子性可以根据当前定义的范围而改变
    原子性的设计:首先定义上下文或者范围,其次是考虑操作是否是原子性的
    不可分割和不可中断:
    i++在程序内部的操作可分为
    - 检索i的值
    - 增加i的值
    - 存储i的值
    每一步都是原子的,但是结合在一起就可能不是了,取决于上下文
data := 0
	w := sync.WaitGroup{}
	for i := 0; i < 100000; i++{
		w.Add(1)
		go func() {
			data++
			w.Done()
		}()
	}
	w.Wait()
	fmt.Println("data:",data)

打印的data值是不确定的

3、内存访问同步
数据竞争的例子:

var data int
go func(){
	data++
}()
if data == 0{
	fmt.Printf("The data:%d\n",data)
} else{
	fmt.Printf("the data:%d\n",data)
}

程序总是会有一个输出,在有数据竞争的情况下输出将不会正确
程序中有三个临界区(独占访问共享资源的部分):
- goroutine在增加数据变量
- if在检查data==0是否成立
- fmt.Printf检索并输出数据的值
通常的会使用锁机制来同步内存访问,但是锁机制自动解决数据竞争或逻辑正确性问题,而且会造成性能问题

本书作者带你一步一步深入这些方法。你将理解 Go语言为何选定这些并发模型,这些模型又会带来什么问题,以及你如何组合利用这些模型中的原语去解决问题。学习那些让你在独立且自信的编写与实现任何规模并发系统时所需要用到的技巧和工具。 理解Go语言如何解决并发难以编写正确这一根本问题。 学习并发与并行的关键性区别。 深入到Go语言的内存同步原语。 利用这些模式中的原语编写可维护的并发代码。 将模式组合成为一系列的实践,使你能够编写大规模的分布式系统。 学习 goroutine 背后的复杂性,以及Go语言的运行时如何将所有东西连接在一起。 作者简介 · · · · · · Katherine Cox-Buday是一名计算机科学家,目前工作于 Simple online banking。她的业余爱好包括软件工程、创作、Go 语言(igo、baduk、weiquei) 以及音乐,这些都是她长期的追求,并且有着不同层面的贡献。 目录 · · · · · · 前言 1 第1章 并发概述 9 摩尔定律,Web Scale和我们所陷入的混乱 10 为什么并发很难? 12 竞争条件 13 原子性 15 内存访问同步 17 死锁、活锁和饥饿 20 确定并发安全 28 面对复杂性的简单性 31 第2章 对你的代码建模:通信顺序进程 33 并发与并行的区别 33 什么是CSP 37 如何帮助你 40 Go语言并发哲学 43 第3章 Go语言并发组件 47 goroutine 47 sync包 58 WaitGroup 58 互斥锁和读写锁 60 cond 64 once 69 池 71 channel 76 select 语句 92 GOMAXPROCS控制 97 小结 98 第4章 Go语言并发模式 99 约束 99 for-select循环103 防止goroutine泄漏 104 or-channel 109 错误处理112 pipeline 116 构建pipeline的最佳实践 120 一些便利的生成器 126 扇入,扇出 132 or-done-channel 137 tee-channel 139 桥接channel模式 140 队列排队143 context包 151 小结 168 第5章 大规模并发 169 异常传递169 超时和取消 178 心跳 184 复制请求197 速率限制199 治愈异常的goroutine 215 小结 222 第6章 goroutine和Go语言运行时 223 工作窃取223 窃取任务还是续体 231 向开发人员展示所有这些信息 240 尾声 240 附录A 241
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值