golang append的并发问题
博客专区 > anoty 的博客 > 博客详情
golang append的并发问题
anoty 发表于11个月前
golang append的并发问题
  • 发表于 11个月前
  • 阅读 59
  • 收藏 0
  • 点赞 0
  • 评论 2

【腾讯云】如何购买服务器最划算?>>>   

摘要: golang append的并发问题

先看一段代码

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	s := make([]int, 0, 1000)

	for i := 0; i < 1000; i++ {
		v := i
		wg.Add(1)
		go func() {
			s = append(s, v)
			wg.Done()
		}()
	}

	wg.Wait()
	fmt.Printf("%v\n", len(s))
}

结果

第一次:928
第二次:945
第三次:986
……

多运行几次你就会发现,slice长度并不是1000,而是不停的在变,为什么呢?(如果这个代码你无法重现,你可以尝试将1000改为更大的数字)

因为append并不是并发安全的。

我们举一个简单例子,比如,当A和B两个协程运行append的时候同时发现s[1]这个位置是空的,他们就都会把自己的值放在这个位置,这样他们两个的值就会覆盖,造成数据丢失。

那该怎么写?最简单的方式就是用锁,贴一个例子

package main

import (
	"fmt"
	"sync"
)

func main() {
	var (
		wg    sync.WaitGroup
		mutex sync.Mutex
	)

	s := make([]int, 0, 1000)

	for i := 0; i < 1000; i++ {
		v := i
		wg.Add(1)
		go func() {
			mutex.Lock()
			s = append(s, v)
			mutex.Unlock()
			wg.Done()
		}()
	}

	wg.Wait()
	fmt.Printf("%v\n", len(s))
}

运行一下这个例子就会发现,s的长度总是1000。

标签: Golang 并发
共有 人打赏支持
粉丝 10
博文 18
码字总数 12763
评论 (2)
hlj2722
第一个例子,我运行了好多次也并无你说的问题呢,我的GO 版本 1.7.4
anoty

引用来自“hlj2722”的评论

第一个例子,我运行了好多次也并无你说的问题呢,我的GO 版本 1.7.4
那就把1000改为改大一点试试
×
anoty
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: