6

golang Map 并发安全的几个点

 2 years ago
source link: http://chen-tao.github.io/2018/01/30/go-sync-map/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

golang Map 并发安全的几个点

发表于 2018-01-30

| 分类于 Golang

有几个坑,需要注意一下
// map_safe.go
// Copyright (C) 2018 chentao <[email protected]>
// Distributed under terms of the MIT license.
package main
import (
"fmt"
"sync"
"time"
type ctr struct {
sync.RWMutex
m map[string]int
func main() {
counter := &ctr{m: make(map[string]int)}
for i := 0; i < 10; i++ {
go bc(counter)
//for i := 0; i < 10; i++ {
// go set(counter, i*10)
//for i := 0; i < 10; i++ {
// go get(counter)
time.Sleep(time.Second * 2)
func bc(counter *ctr) {
for i := 0; i < 10; i++ {
go set(counter, i)
for i := 0; i < 10; i++ {
go get(counter)
// counter 这里必须是引用
func set(counter *ctr, v int) {
counter.Lock()
defer func() {
counter.Unlock()
fmt.Printf("set unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("set unlock count addr %p \n", &counter.m)
fmt.Printf("set unlock all addr %p \n", &counter)
//counter.m["some_key"] = v
counter.m["some_key"] = counter.m["some_key"] + v
//time.Sleep(time.Millisecond * 10)
fmt.Println("some_key set:", counter.m["some_key"])
func get(counter *ctr) {
counter.RLock()
defer func() {
counter.RUnlock()
fmt.Printf("get unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("get unlock count addr %p \n", &counter.m)
fmt.Printf("get unlock all addr %p \n", &counter)
n := counter.m["some_key"]
fmt.Println("some_key get:", n)
// map_safe.go
// Copyright (C) 2018 chentao <[email protected]>
// Distributed under terms of the MIT license.
package main
import (
"fmt"
"sync"
"time"
"unsafe"
type ctr2 struct {
sync.RWMutex
m map[string]int
func main() {
counter := ctr2{m: make(map[string]int)}
for i := 0; i < 10; i++ {
go counter.bc()
//for i := 0; i < 10; i++ {
// go set(counter, i*10)
//for i := 0; i < 10; i++ {
// go get(counter)
time.Sleep(time.Second * 2)
// counter这里都OK
func (counter *ctr2) bc() {
for i := 0; i < 10; i++ {
go counter.set(i)
for i := 0; i < 10; i++ {
go counter.get()
func (counter *ctr2) set(v int) {
counter.Lock()
defer func() {
counter.Unlock()
fmt.Printf("set unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("set unlock count addr %p \n", &counter.m)
fmt.Printf("set unlock all addr %p \n", &(*counter))
fmt.Printf("set unlock all addr %p \n", unsafe.Pointer(counter))
fmt.Printf("set unlock all addr %p \n", counter)
}() // 注意这几个对象引用和地址的区分
//counter.m["some_key"] = v
counter.m["some_key"] = counter.m["some_key"] + v
//time.Sleep(time.Millisecond * 10)
fmt.Println("some_key set:", counter.m["some_key"])
func (counter *ctr2) get() {
counter.RLock()
defer func() {
counter.RUnlock()
fmt.Printf("get unlock mutex addr %p \n", &counter.RWMutex)
fmt.Printf("get unlock count addr %p \n", &counter.m)
fmt.Printf("get unlock all addr %p \n", &(*counter))
fmt.Printf("get unlock all addr %p \n", unsafe.Pointer(counter))
fmt.Printf("get unlock all addr %p \n", counter)
n := counter.m["some_key"]
fmt.Println("some_key get:", n)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK