文档章节

golang append的并发问题

anoty
 anoty
发布于 2017/02/15 21:57
字数 289
阅读 84
收藏 0
点赞 0
评论 2

先看一段代码

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。

© 著作权归作者所有

共有 人打赏支持
anoty
粉丝 12
博文 21
码字总数 14053
作品 0
浦东
加载中

评论(2)

anoty
anoty

引用来自“hlj2722”的评论

第一个例子,我运行了好多次也并无你说的问题呢,我的GO 版本 1.7.4
那就把1000改为改大一点试试
h
hlj2722
第一个例子,我运行了好多次也并无你说的问题呢,我的GO 版本 1.7.4
基于 PHP 协程的网络服务框架--Zan PHP Framework

Zan PHP Framework 是有赞开源的基于 PHP 协程的网络服务框架,提供最简单的方式开发面向 C10K+ 的高并发SOA服务和RPC服务。 该项目每天为2,000+个服务提供300,000,000+次访问量支持,广泛应...

匿名
2017/06/21
2.1K
6
Zan-Group/zanphp

基于 PHP 协程的网络服务框架,提供最简单的方式开发面向 C10K+ 的高并发SOA服务和RPC服务。 每天为2,000+个服务提供300,000,000+次访问量支持,广泛应用于有赞各项业务。 核心特性 基于 实现...

Zan-Group
2017/06/21
0
0
goroutine, channel 和 CSP

引子 老听 clojure 社区的人提起 core.async ,说它如何好用,如何简化了并发编程的模型,不由得勾起了我的好奇心,想了解一番其思想的源头:CSP 模型及受其启发的 goroutine 和 channel 。 ...

wangxuwei
01/29
0
0
golang: Golang 并发模式:超时和继续 Go Concurrency Patterns:

golang: Golang 并发模式:超时和继续 Go Concurrency Patterns: Timing out, moving on Go eclipse plugin chi/Golang 1.6: 在服务器中加入防止panic的Middleware及Handler 开源Go野心勃勃,......

d_watson
2016/06/02
36
0
为什么 PHPer 应当学习 Golang

熟悉我的朋友应当知道,近些年的大部分时间我的工作都会多少和 PHP 相关。随着 PHP 有着越来越深入的了解,以及遇到越来越多的不同业务时,使用 PHP 总会让我有一种莫名的无力感。当然,并不...

龙鸟
2012/11/28
0
4
golang VS php 性能对比

原文 http://www.isno.cn/2013/12/golang-vs-php/ 在工作的项目中,我的主要开发语言是php,因需求或者为弥补php的缺陷,需要为php做各种各样的扩展,比如php本身不支持线程,没有队列,进程也...

神仙
2013/12/19
24.4K
33
golang: 常用数据类型底层结构分析

虽然golang是用C实现的,并且被称为下一代的C语言,但是golang跟C的差别还是很大的。它定义了一套很丰富的数据类型及数据结构,这些类型和结构或者是直接映射为C的数据类型,或者是用C struc...

陈亦
2014/01/29
0
9
Mecached Client for Golang

Memcached Client for Golang golang版本的memcached客户端,使用二进制协议,支持分布式,支持连接池,支持多种数据格式 特性 支持多server集群 与memcached使用二进制协议通信 支持连接池 ...

盘古大叔
2016/02/26
382
0
mysql协议解析之握手协议(handshake)

要解析mysql协议需要了解一下知识和软件 一、wireshark(https://www.wireshark.org) wireshark 是一款网络抓包工具,可以让我们很方便的查看mysql协议。 二、网络字节序(http://www.cnblogs.c...

曾经的十字镐
2017/11/02
0
0
在windows下配置Eclipse + go环境 Eclipse平台下配置Go语言开发环境(Win

mongoDB: mongoDB数据库基本操作 Programming in Go (Golang) – Setting up a Mac OS X Development Environment 造完美的go开发环境 在windows下配置Eclipse + go环境 Eclipse平台下配置G......

d_watson
2016/06/03
26
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

shell及python脚本方式登录服务器

一、问题 在工作过程中,经常会遇见需要登录服务器,并且因为安全的原因,需要使用交互的方式登录,而且shell、python在工作中也经常用到,并且可以提供交互的功能。都是利用了expect、spawn...

yangjianzhou
5分钟前
0
0
upstream sent too big header while reading...

nginx 报错:1736 upstream sent too big header while reading response header from upstream 1. 一般处理 location ~ \.php$ { #增加下面两句 fastcgi_buffer_size 128k; ......

dubox
15分钟前
0
0
Python解析配置文件模块:ConfigPhaser

import configparser as pa# [SectionA]# a = aa# b = bb# c = cc# [SectionB]# optionint = 1# optionfloat = 1.1# optionstring = string#https://www.cnblogs.com/a......

易野
22分钟前
0
0
Java基础——面向对象

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 Object的方法: clone() Object 克隆 to Strin...

凯哥学堂
24分钟前
0
0
rabbitmq学习记录(八)消息发布确认机制

RabbitMQ服务器崩了导致的消息数据丢失,已经持久化的消息数据我们可以通过消息持久化来预防。但是,如果消息从生产者发送到vhosts过程中出现了问题,持久化消息数据的方案就无效了。 Rabbit...

人觉非常君
28分钟前
0
0
毕业5年,我是怎么成为年薪30W的运维工程师

#转载# 我在大学读的是计算机专业,但大学毕业之后,进入到一家私企进行工作,工作的内容类似于网管,会经常的去修电脑,去做水晶头等内容。刚开始工作,也没想太多,最想的是丰富自己的工作...

Py爱好
35分钟前
1
0
大数据基础知识,大数据学习,涉及的知识点

一、什么是大数据 一种规模大到在获取、存储、管理、分析方面大大超出了传统数据库软件工具能力范围的数据集合,具有海量的数据规模、快速的数据流 转、多样的数据类型和价值密度低四大特征。...

董黎明
51分钟前
0
0
Linux CentOS 7上安装极点五笔

话说几天前在新买的惠普笔记本上成功地安装了Linux CentOS 7操作系统、Nvidia Quandro P600驱动程序及X Window,并在VMware下安装Red Hat教学环境,彻底跳出Windows的苦海,但仍然有一件事不...

大别阿郎
今天
17
0
2018年7月20日集群课程

一、集群介绍 集群,简单地说是指一组(若干个)相互独立的计算机,利用高速通信网络组成一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运行各自服务的独立服务器。 ...

人在艹木中
今天
0
0
spark开发机中调试snappy

目的 在Idea中的点击运行,使spark可以直接读取snappy 自己编译hadoop,以支持snappy的压缩。 自己编译的目的就是要得到支持snappy文件读写的动态链接库。如果可以在网上下载,可以跳过自行编...

benny周
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部