golang

golang 关于锁 mutex,踩过的坑

£可爱£侵袭症+ 提交于 2019-12-04 23:59:33
伪代码声明:请无视一些拼写错误 mutex实例无需实例化,声明即可使用 func add ( ) { var mutex sync . Mutex mutex . Lock ( ) defer mutex . Unlock ( ) fmtPrintln ( "test lock" ) } mutex在传递给外部使用的时候,需要传指针,不然传的是拷贝,会引起锁失败。并且指针的mutex是一定要实例化过的。 func add ( ) * sync . Mutex { var m = & sync . Mutex { } return m } 对同一个锁,进行多次锁,会死锁 func a ( ) { var mutex sync . Mutex mutex . Lock ( ) mutex . Lock ( ) // dead lock } 对一个RWLock进行同时Lock()和RLock()会死锁. func a ( ) { var mutex sync . RWMutex mutex . RLock ( ) mutex . Lock ( ) // dead lock } 这意味着如果一个操作函数里同时包含写和读,千万不要这么写 type Object struct { Data [ ] interface { } L sync . RWMutex } func WR ( o

golang 中map并发读写操作

允我心安 提交于 2019-12-04 23:58:44
go中map并发使用是不安全的,当你使用goroutine同时对一个map进行读写操作时,不确定会发生什么(由于读写执行顺序不确定造成的).针对这种情况,我们要添加读写锁对 sync.RWMutex 其进行同步. var counter = struct{ sync.RWMutex m map[string]int }{m: make(map[string]int)} 从counter读取数据,使用读锁 counter.RLock() n := counter.m["some_key"] counter.RUnlock() fmt.Println("some_key:", n) 向counter写数据,使用写锁 counter.Lock() counter.m["some_key"]++ counter.Unlock() 参考: http://blog.golang.org/go-maps-in-action 转载于:https://www.cnblogs.com/msnsj/p/4242583.html 来源: CSDN 作者: weixin_34050427 链接: https://blog.csdn.net/weixin_34050427/article/details/94249799

golang多个routine操作map或者slice需要上锁

妖精的绣舞 提交于 2019-12-04 23:58:16
最近写服务器代码,运行期间突然panic,最后找到原因是因为map不是线程安全的,那这就简单啦,来一把读写锁。以下附上代码: type QueryExchangerFlowBySomeTime struct { com.HandlerDemo } func (self *QueryExchangerFlowBySomeTime) FuckBody (body interface {}) (result interface {}, err error ) { obj := *body.(* map [ string ] interface {}) ip :=to. String (obj[ "ip" ]) granule :=to. Int64 (obj[ "granule" ]) log. Println ( "传入:" ,granule) retMap := make ( map [ string ] interface {}) retMap[ "starttime" ]= GetHisTime () ips := GetAllMac (ip) retData :=ReqDataHub{} time_out := make ( chan int , 2 ) go ReqTimeOut (time_out, 1 ,DATAHUB_REQ_TIME) var wg sync

golang 解读(2) sync.Map

与世无争的帅哥 提交于 2019-12-04 23:57:07
sync.map就是1.9版本带的线程安全map. [[在Go 1.6之前, 内置的map类型是部分goroutine安全的,并发的读没有问题,并发的写可能有问题。自go 1.6之后, 并发地读写map会报错, 所以go 1.9之前的解决方案是额外绑定一个锁,封装成一个新的struct或者单独使用锁都可以。 在Go官方blog的Go maps in action一文中,提供了一种简便的解决方案。 var counter = struct{ sync.RWMutex // 读写锁 m map[string]int }{m: make(map[string]int)} 它使用嵌入struct为map增加一个读写锁。 读数据的时候很方便的加锁: counter.RLock() // 读锁定 n := counter.m["some_key"] counter.RUnlock() fmt.Println("some_key:", n) 写数据的时候: unter.Lock() // 写锁定 counter.m["some_key"]++ counter.Unlock() golang中sync包实现了两种锁 Mutex (互斥锁:适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁) 和RWMutex(读写锁:该锁可以加多个读锁或者一个写锁

golang 中map并发读写

亡梦爱人 提交于 2019-12-04 23:53:58
项目上之前出现map并发问题,查找资料后自己整理一下。 代码如下: //map 并发存取 type BeeMap struct { lock *sync.RWMutex bm map [ string ] interface {} } func NewBeeMap() *BeeMap { return &BeeMap{ lock: new (sync.RWMutex), bm: make ( map [ string ] interface {}), } } //Get from maps return the k's value func (m *BeeMap) Get(k string ) interface {} { m.lock.RLock() defer m.lock.RUnlock() if val, ok := m.bm[k]; ok { return val } return nil } // Maps the given key and value. Returns false // if the key is already in the map and changes nothing. func (m *BeeMap) Set(k string , v interface {}) bool { m.lock.Lock() defer m.lock.Unlock

golang中map的并发 syncmap详解

只谈情不闲聊 提交于 2019-12-04 23:53:01
golang中map当前版本默认直接并发写会报concurrent map writes 错误 在golang中要实现并发读写的话有三种目前通用的方式: 1. 使用读写锁sync.RWMutex,在读的时候使用读锁,使用的时候如下代码,效率较低: var counter = struct{ sync.RWMutex //读写锁 m map[string]int }{m: make(map[string]int)} counter.RLock() // 读锁定 n := counter.m["some_key"] counter.RUnlock() unter.Lock()// 写锁定 counter.m["some_key"]++ counter.Unlock() 2. 使用golang官方包的syncmap,效率比第一种方式要高。源码在原生包sync.Map,或者github: https://github.com/golang/sync/tree/master/syncmap 3. 使用其他开源包的concurrentmap,或者自己实现,可以参考java的concurrentmap,使用shard将数据分块,每个锁只针对一个块。 该文章主要讲syncmap的流程,并在源码中翻译原来注释加入一些中文注释帮助理解, 配合源码食用效果更佳。 总述: syncmap是由两个map构成

golang map的遍历

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-04 23:51:35
遍历key package main import ( "fmt" ) func main() { var mymap map [ string ] string mymap = map [ string ] string { "1a" : "Very" , "2b" : "good" , "3c" : "day" } for one := range mymap { fmt.Println(one) } } output: 1a 2b 3c 遍历value package main import ( "fmt" ) func main() { var mymap map [ string ] string mymap = map [ string ] string { "1a" : "Very" , "2b" : "good" , "3c" : "day" } for _,value := range mymap { fmt.Println(value) } } output: Very good day 遍历key-value package main import ( "fmt" ) func main() { var mymap map [ string ] string mymap = map [ string ] string { "1a" : "Very" , "2b

[Golang] 关于Sync.Map的使用

喜夏-厌秋 提交于 2019-12-04 23:50:28
简介: sync.Map这个数据结构是线程安全的(基本类型Map结构体在并发读写时会panic严重错误),它填补了Map线程不安全的缺陷,不过最好只在需要的情况下使用。它一般用于并发模型中对同一类map结构体的读写,或其他适用于sync.Map的情况。 关于sync.Map的源码解析文章: Go 1.9 sync.Map揭秘 正文: 它主要五个方法及其功能简介: 1、Store 存 key,value 2、LoadOrStore 取&存-具体看代码 3、Load 取key对应的value 4、Range 遍历所有的key,value 5、Delete 删除key,及其value package main import ( "fmt" "sync" ) func main() { var m sync.Map //Store m.Store(1,"a") m.Store(2,"b") //LoadOrStore //若key不存在,则存入key和value,返回false和输入的value v,ok := m.LoadOrStore("1","aaa") fmt.Println(ok,v) //false aaa //若key已存在,则返回true和key对应的value,不会修改原来的value v,ok = m.LoadOrStore(1,"aaa") fmt.Println

golang中的map与sync.map解析

我只是一个虾纸丫 提交于 2019-12-04 23:50:08
map map的底层实现 golang中的map采用了HashTable的实现,通过数组+链表实现的。一个哈希表会有一定数量的桶,哈希表将键值对均匀存储到这些桶中。哈希表在存储键值对时,会先用哈希函数把键值转换为哈希值,哈希表先用哈希值的低几位去定位到一个哈希桶,然后再去这个哈希桶中查找这个键。由于键值对总是被捆绑在一起存在,一旦找到了键,就找到了值。go的字典中,每一个键值对都是它的哈希值代表的, 字典不会独立存储任何键的键值,但会独立存储他们的哈希值 map的键类型不能是哪些类型 不能是函数类型、字典类型、切片类型。 原因:go语言规范规定,键类型的值之间必须可以施加==操作符和!=操作符,即必须支持判等操作,由于函数类型,字典类型,切片类型不支持判等操作 如果键类型是接口类型,那么键值的实际类型也不能是上述3种,否则会已发panic 如果键的类型是数组类型,那么还要确保该类型的元素类型不是函数类型、字典类型或切片类型。 如果键的类型是结构体类型,那么还要保证其中字段的类型的合法性。无论不合法的类型被埋藏得有多深,比如map[[1][2][3][]string]int,Go 语言编译器都会把它揪出来。 map对键类型有何要求 求哈希和判等操作比较快的对应的类型适合做键类型。 不建议使用高级数据类型作为类型的原因不仅仅是值求哈希以及判等速度比较慢,而且值存在变数

[Golang] 关于Sync.Map的使用

风流意气都作罢 提交于 2019-12-04 23:49:49
转自 https://blog.csdn.net/sc_lilei/article/details/81390185 简介: sync.Map这个数据结构是线程安全的(基本类型Map结构体在并发读写时会panic严重错误),它填补了Map线程不安全的缺陷,不过最好只在需要的情况下使用。它一般用于并发模型中对同一类map结构体的读写,或其他适用于sync.Map的情况。 关于sync.Map的源码解析文章: Go 1.9 sync.Map揭秘 正文: 它主要五个方法及其功能简介: 1、Store 存 key,value 2、LoadOrStore 取&存-具体看代码 3、Load 取key对应的value 4、Range 遍历所有的key,value 5、Delete 删除key,及其value package main import ( "fmt" "sync" ) func main() { var m sync.Map //Store m.Store(1,"a") m.Store(2,"b") //LoadOrStore //若key不存在,则存入key和value,返回false和输入的value v,ok := m.LoadOrStore("1","aaa") fmt.Println(ok,v) //false aaa //若key已存在