在go语言中安全问题之并发保护场景示例
Go  /  管理员 发布于 1个月前   89
go语言安全问题之并发保护场景
场景1:禁止在闭包中直接调用循环变量
在循环中启动协程,当协程中使用到了循环的索引值,由于多个协程同时使用同一个变量会产生数据竞争,造成执行结果异常。
示例代码:
// bad
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) var group sync.WaitGroup
for i := 0; i < 5; i++ { group.Add(1) go func() { defer group.Done() fmt.Printf("%-2d", i) // 这里打印的i不是所期望的
}() } group.Wait()}
// good
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) var group sync.WaitGroup
for i := 0; i < 5; i++ { group.Add(1) go func(j int) { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in start()") } group.Done() }() fmt.Printf("%-2d", j) // 闭包内部使用局部变量
}(i) // 把循环变量显式地传给协程
} group.Wait()}
场景2:禁止并发写 map
并发写 map 容易造成程序崩溃并异常退出,建议加锁保护
示例代码:
// bad
func main() {
m := make(map[int]int) // 并发读写
go func() { for { _ = m[1] } }() go func() { for { m[2] = 1 } }() select {}}
场景3:确保并发安全
敏感操作如果未作并发安全限制,可导致数据读写异常,造成业务逻辑限制被绕过。可通过同步锁或者原子操作进行防护。
通过同步锁共享内存
示例代码:
// good
var count int
func Count(lock *sync.Mutex) {
lock.Lock() // 加写锁
count++ fmt.Println(count) lock.Unlock() // 解写锁,任何一个Lock()或RLock()均需要保证对应有Unlock()或RUnlock()
}
func main() {
lock := &sync.Mutex{} for i := 0; i < 10; i++ { go Count(lock) // 传递指针是为了防止函数内的锁和调用锁不一致
} for { lock.Lock() c := count lock.Unlock() runtime.Gosched() // 交出时间片给协程
if c > 10 { break } }}
使用 sync/atomic 执行原子操作
// good
import (
"sync" "sync/atomic")
func main() {
type Map map[string]string var m atomic.Value m.Store(make(Map)) var mu sync.Mutex // used only by writers read := func(key string) (val string) { m1 := m.Load().(Map) return m1[key] } insert := func(key, val string) { mu.Lock() // 与潜在写入同步
defer mu.Unlock() m1 := m.Load().(Map) // 导入struct当前数据
m2 := make(Map) // 创建新值
for k, v := range m1 { m2[k] = v } m2[key] = val m.Store(m2) // 用新的替代当前对象
} _, _ = read, insert}
路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..博主 在
科学上网翻墙之v2rayN-Core客户端免费公益节点使用教程中评论 @ mashrdn 多切换几个节点测试,免费ssr是没那么稳..mashrdn 在
科学上网翻墙之v2rayN-Core客户端免费公益节点使用教程中评论 V2rayn免费节点添加上去了,youtobe无法打开网页,是怎么回事..张伟 在
科学上网翻墙之v2rayN-Core客户端免费公益节点使用教程中评论 3q!有用,不过免费节点隔天就要去git上复制新的导进去..博主 在
科学上网翻墙访问Google , 上外网神器佛跳墙VPN(永久免费)使用流程步骤中评论 该篇教程已不能用了,告知大家,免的老有老铁问我!..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号