首页 > 其他分享 >go笔记-并发赋值安全性

go笔记-并发赋值安全性

时间:2023-01-30 20:24:40浏览次数:73  
标签:安全 var 并发 func go 赋值

参考资料

https://cloud.tencent.com/developer/article/1810536

并发赋值安全/不安全的类型

  1. 并发赋值安全的类型:
    字节型,布尔型、整型、浮点型、字符型、指针、函数
    这些类型可由一条机器指令完成赋值

  2. 数组由一个或多个元素组成,大部分情况并发不安全
    注意:当位宽不大于 64 位且是 2 的整数次幂(8,16,32,64),那么其并发赋值是安全的。

  3. struct 或底层是 struct 的类型并发赋值大部分情况并发不安全,类型有:
    复数、字符串、 数组、切片、字典、通道、接口
    注:当 struct 赋值时退化为单个字段由一个机器指令完成赋值时,并发赋值又是安全的。这种情况有:
    3.1 实部或虚部相同的复数的并发赋值
    3.2 等长字符串的并发赋值
    3.3 同长度同容量切片的并发赋值
    3.4 同一种具体类型不同值并发赋给接口

例3.1: 实部或虚部相同的复数的并发赋值

// 线程不安全
var g complex64
go func() {
	g = complex(1, 2)
}()

go func() {
	g = complex(3, 4)
}()
// 线程安全
var g complex64
go func() {
	g = complex(1, 2)
}()

go func() {
	g = complex(1, 3)  // 实部相同
}()

例3.2 等长字符串的并发赋值

// 线程不安全
var s string
go func() {
	s = "ab"
}()
go func() {
	s = "abc"
}()
// 线程安全
var s string
go func() {
	s = "abc"
}()
go func() {
	s = "abd"  // 字符串长度相同, 线程安全
}()

完整例子

点击打开完整示例
func main() {
	var s string
	i := 0
	for {
		var wg sync.WaitGroup
		var endWg sync.WaitGroup
		// 协程 1
		endWg.Add(2)
		wg.Add(1)
		go func() {
			wg.Wait()
			s = "ab"
			endWg.Done()
		}()

		// 协程 2
		go func() {
			wg.Wait()
			s = "abc"
			endWg.Done()
		}()
		wg.Done()    // 协程内同时进行赋值
		endWg.Wait() // 等待两次并发赋值完成

		i++
		// 赋值异常判断
		if s != "ab" && s != "abc" {
			fmt.Printf("concurrent assignment error, i=%v s=%v", i, s)
			break
		}
	}
}

标签:安全,var,并发,func,go,赋值
From: https://www.cnblogs.com/gnivor/p/17077152.html

相关文章

  • 【Python】爬虫实战-基于代理池的高并发爬虫
    最近在写一个基于代理池的高并发爬虫,目标是用单机从某网站API爬取十亿级别的JSON数据。代理池有两种方式能够实现爬虫对代理池的充分利用:搭建一个TunnelProxy服务......
  • 0145-Go-环境变量
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/environment-variables目标使用Go语言的环境变量。示例packagemainimport("fmt"......
  • 0146-Go-HTTP 客户端
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/http-clients目标使用Go语言的HTTP客户端。示例packagemainimport("bufio"......
  • 0147-Go-HTTP 服务端
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/http-servers目标使用Go语言HTTP服务端。示例packagemainimport("fmt""ne......
  • 0148-Go-上下文
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/context目标使用Go语言的上下文。示例packagemainimport("fmt""net/http""time"......
  • 0149-Go-生成进程
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/spawning-processes目标使用Go语言生成进程。示例packagemainimport("fmt""......
  • 0150-Go-执行进程
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/execing-processes目标使用Go语言执行进程。示例packagemainimport("os""os......
  • 0151-Go-信号
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/signals目标使用Go语言的信号。示例packagemainimport( "fmt" "os" "os/signal" "......
  • 0152-Go-退出
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/exit目标退出Go程序。示例packagemainimport("fmt""os")funcmain(){......
  • 0138-Go-文件目录
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/directories目标使用Go语言处理文件目录。示例packagemainimport("fmt""os"......