校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁(yè) > 知識(shí)庫(kù) > 快速解決Golang Map 并發(fā)讀寫安全的問題

快速解決Golang Map 并發(fā)讀寫安全的問題

熱門標(biāo)簽:不封卡外呼系統(tǒng) 宿遷便宜外呼系統(tǒng)代理商 鄭州智能語(yǔ)音電銷機(jī)器人價(jià)格 上海極信防封電銷卡價(jià)格 地圖標(biāo)注免費(fèi)定制店 仙桃400電話辦理 湛江crm外呼系統(tǒng)排名 重慶慶云企業(yè)400電話到哪申請(qǐng) 寧波語(yǔ)音外呼系統(tǒng)公司

一、錯(cuò)誤案例

package main
import (
	"fmt"
	"time"
)
var TestMap map[string]string
func init() {
	TestMap = make(map[string]string, 1)
}
func main() {
	for i := 0; i  1000; i++ {
		go Write("aaa")
		go Read("aaa")
		go Write("bbb")
		go Read("bbb")
	}
	time.Sleep(5 * time.Second)
}
func Read(key string) {
	fmt.Println(TestMap[key])
}
func Write(key string) {
	TestMap[key] = key
}

上面代碼執(zhí)行大概率出現(xiàn)報(bào)錯(cuò):fatal error: concurrent map writes

二、問題分析

網(wǎng)上關(guān)于 golang 編程中 map 并發(fā)讀寫相關(guān)的資料很多,但總是都說成 并發(fā)讀寫 造成上面的錯(cuò)誤,到底是 并發(fā)讀 還是 并發(fā)寫 造成的,這個(gè)很多資料都沒有說明。

我們把上面的案例分別在循環(huán)中注釋 Read 和 Write 函數(shù)的調(diào)用,分別測(cè)試 并發(fā)讀 和 并發(fā)寫;

循環(huán)次數(shù)分別測(cè)試了 100、1 w、100 w 次,并發(fā)讀操作絕對(duì)不會(huì)報(bào)上面的錯(cuò),而并發(fā)寫基本都會(huì)報(bào)錯(cuò)。

因此,這個(gè)錯(cuò)誤主要原因是:map 并發(fā)寫。

三、問題原因

為什么 map 并發(fā)寫會(huì)導(dǎo)致這個(gè)錯(cuò)誤? 網(wǎng)絡(luò)上的相關(guān)文章也大都有說明。

因?yàn)?map 變量為 指針類型變量,并發(fā)寫時(shí),多個(gè)協(xié)程同時(shí)操作一個(gè)內(nèi)存,類似于多線程操作同一個(gè)資源會(huì)發(fā)生競(jìng)爭(zhēng)關(guān)系,共享資源會(huì)遭到破壞,因此golang 出于安全的考慮,拋出致命錯(cuò)誤:fatal error: concurrent map writes。

四、解決方案

網(wǎng)上各路資料解決方案較多,主要思路是通過加鎖保證每個(gè)協(xié)程同步操作內(nèi)存。

github 上找到一個(gè) concurrentMap 包,案例代碼修改如下:

package main
import (
 "fmt"
 cmap "github.com/orcaman/concurrent-map"
 "time"
)
var TestMap cmap.ConcurrentMap
func init() {
 TestMap = cmap.New()
}
func main() {
 for i := 0; i  100; i++ {
 go Write("aaa", "111")
 go Read("aaa")
 go Write("bbb", "222")
 go Read("bbb")
 }
 time.Sleep(5 * time.Second)
}
func Read(key string) {
 if v, ok := TestMap.Get(key); ok {
 fmt.Printf("鍵值為 %s 的值為:%s", key, v)
 } else {
 fmt.Printf("鍵值不存在")
 }
}
func Write(key string, value string) {
 TestMap.Set(key, value)
}

五、思考總結(jié)

因?yàn)槲沂且?PHP 打開的編程世界,PHP 語(yǔ)言只有單線程,且不涉及指針操作,變量類型也是弱變量,以 PHP 編程思維剛開始接觸 Golang 時(shí)還比較容易上手,但越往后,語(yǔ)言的特性區(qū)別就體現(xiàn)得越來越明顯,思維轉(zhuǎn)變就越來越大,對(duì)我來說是打開了一個(gè)新世界。

像本文出現(xiàn)的錯(cuò)誤案例,也是因?yàn)樽约簺]有多線程編程的思維基礎(chǔ),導(dǎo)致對(duì)這種問題不敏感,還是花了蠻多時(shí)間理解的。希望對(duì)和我有相似學(xué)習(xí)路線的朋友提供到一些幫助。

補(bǔ)充:Golang Map并發(fā)處理機(jī)制(sync.Map)

Go語(yǔ)言中的Map在并發(fā)情況下,只讀是線程安全的,同時(shí)讀寫線程不安全。

示例:

package main 
import (
 "fmt"
)
var m = make(map[int]int)
func main() {
 //寫入操作
 i:=0
 go func() {
 for{
 i++
 m[1]=i
 }
 
 }()
 //讀操作
 go func() {
 for{
 fmt.Println(m[1])
 }
 
 }()
 //無(wú)限循環(huán),讓并發(fā)程序在后臺(tái)運(yùn)行
 for {
 ;
 }
}

從以上示例可以看出,不斷地對(duì)map進(jìn)行讀和寫,會(huì)出現(xiàn)錯(cuò)誤。主要原因是對(duì)map進(jìn)行讀和寫發(fā)生了競(jìng)態(tài)問題。map內(nèi)部會(huì)對(duì)這種并發(fā)操作進(jìn)行檢查并提前發(fā)現(xiàn)。

如果確實(shí)需要對(duì)map進(jìn)行并發(fā)讀寫操作,可以采用加鎖機(jī)制、channel同步機(jī)制,但這樣性能并不高。

Go語(yǔ)言在1.9版本中提供了一種效率較高的并發(fā)安全的sync.Map。

sync.Map結(jié)構(gòu)如下:

The zero Map is empty and ready for use. A Map must not be copied after first use.
type Map struct {
 mu Mutex
 misses int
}
 
// Load returns the value stored in the map for a key, or nil if no
// value is present.
// The ok result indicates whether value was found in the map.
func (m *Map) Load(key interface{}) (value interface{}, ok bool) { 
}
 
// Store sets the value for a key.
func (m *Map) Store(key, value interface{}) {
 
}
// LoadOrStore returns the existing value for the key if present.
// Otherwise, it stores and returns the given value.
// The loaded result is true if the value was loaded, false if stored.
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) { 
}
 
// Delete deletes the value for a key.
func (m *Map) Delete(key interface{}) { 
} 
 
// Range calls f sequentially for each key and value present in the map.
// If f returns false, range stops the iteration.
//
// Range does not necessarily correspond to any consistent snapshot of the Map's
// contents: no key will be visited more than once, but if the value for any key
// is stored or deleted concurrently, Range may reflect any mapping for that key
// from any point during the Range call.
//
// Range may be O(N) with the number of elements in the map even if f returns
// false after a constant number of calls.
func (m *Map) Range(f func(key, value interface{}) bool) { 
}
 
func (m *Map) missLocked() {
 
}
 
func (m *Map) dirtyLocked() {
 
}

其實(shí),sync.Map內(nèi)部還是進(jìn)行了加鎖機(jī)制,不過進(jìn)行了一定的優(yōu)化。

sync.Map使用示例:

package main 
import (
 "fmt"
 "sync"
 "time"
)
 
var m1 sync.Map 
func main() {
 i := 0
 go func() {
 for {
 i++
 m1.Store(1, i)
 time.Sleep(1000)
 }
 }()
 go func() {
 for{
 time.Sleep(1000)
 fmt.Println(m1.Load(1))
 }
 
 }()
 for {
 ;
 }
}

成功運(yùn)行效果如下:

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • 關(guān)于golang高并發(fā)的實(shí)現(xiàn)與注意事項(xiàng)說明
  • 基于Golang 高并發(fā)問題的解決方案
  • 使用golang編寫一個(gè)并發(fā)工作隊(duì)列
  • golang 并發(fā)編程之生產(chǎn)者消費(fèi)者詳解
  • Golang 并發(fā)以及通道的使用方式
  • 淺談golang并發(fā)操作變量安全的問題
  • golang中的并發(fā)和并行

標(biāo)簽:海南 儋州 電子產(chǎn)品 安康 物業(yè)服務(wù) 遼寧 青海 西雙版納

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《快速解決Golang Map 并發(fā)讀寫安全的問題》,本文關(guān)鍵詞  快速,解決,Golang,Map,并發(fā),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《快速解決Golang Map 并發(fā)讀寫安全的問題》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于快速解決Golang Map 并發(fā)讀寫安全的問題的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    欧美精品vⅰdeose4hd| 国产高清不卡二三区| 欧美日韩久久久一区| 日韩伦理电影网| 丁香天五香天堂综合| 日本一二三四高清不卡| 成人av网在线| 亚洲视频在线一区| 午夜视频在线观看一区二区| 成人ar影院免费观看视频| 99久久久免费精品国产一区二区| xfplay精品久久| 粉嫩欧美一区二区三区高清影视 | 成人精品小蝌蚪| 亚洲伦在线观看| 欧美精品乱码久久久久久按摩| 国产九色sp调教91| 亚洲午夜视频在线观看| 精品sm捆绑视频| 91黄色免费版| 奇米精品一区二区三区在线观看一| 精品国产精品一区二区夜夜嗨| 9i看片成人免费高清| 蜜桃视频在线一区| 伊人性伊人情综合网| 国产亚洲一区二区三区四区| 欧美高清激情brazzers| 99久久综合国产精品| 日韩精品国产精品| 中文字幕在线观看一区二区| 在线电影一区二区三区| av激情综合网| 国产精品中文有码| 五月婷婷综合在线| 青青国产91久久久久久| 亚洲一二三四区| 色综合天天做天天爱| 三级一区在线视频先锋| 国产精品视频yy9299一区| 欧美色精品在线视频| 欧美一级电影网站| 在线播放中文字幕一区| 国产在线精品一区二区不卡了| 中文字幕一区二区三区av| 日韩一区国产二区欧美三区| 91原创在线视频| 风流少妇一区二区| 精品一区二区在线视频| 日韩成人av影视| 一区二区三区四区激情| 18成人在线视频| 中文字幕第一区| 国产调教视频一区| 久久毛片高清国产| 精品国产一区久久| 欧美亚日韩国产aⅴ精品中极品| 免费不卡在线视频| 日韩精品成人一区二区在线| 亚洲va欧美va人人爽午夜| 亚洲国产一区在线观看| 亚洲国产三级在线| 亚洲成人综合在线| 亚洲福利一区二区三区| 首页国产欧美日韩丝袜| 日本成人在线看| 精品一区二区三区影院在线午夜| 免费观看久久久4p| 韩国一区二区在线观看| 精品一区二区在线视频| 国产suv精品一区二区三区| 岛国精品在线播放| 色狠狠桃花综合| 欧美亚洲愉拍一区二区| 91麻豆精品久久久久蜜臀| 日韩视频一区二区三区| 久久亚洲精品国产精品紫薇| 国产亚洲综合色| 综合色中文字幕| 亚洲成人777| 精品在线观看视频| 成人v精品蜜桃久久一区| 色狠狠综合天天综合综合| 欧美影院午夜播放| 日韩三级视频在线看| 国产免费久久精品| 亚洲另类一区二区| 九九久久精品视频| 国产精品久久久一本精品| 91精品国产91久久久久久最新毛片 | 亚洲日本在线视频观看| 亚洲午夜精品17c| 精品一区二区三区久久久| 99久久久无码国产精品| 91精品国产色综合久久久蜜香臀| 久久精品欧美日韩| 日本亚洲视频在线| 91成人免费在线视频| 欧美精品一区二区精品网| 亚洲国产欧美在线人成| 粉嫩高潮美女一区二区三区| 91精品国产麻豆| 亚洲精品乱码久久久久久黑人| 精品一区二区在线免费观看| 欧美在线三级电影| 国产精品毛片久久久久久久| 免费成人美女在线观看.| 欧美在线视频全部完| 亚洲视频香蕉人妖| 国产成人午夜99999| 91.com在线观看| 亚洲高清一区二区三区| 日本韩国欧美在线| 中文字幕一区二区三区视频| 成人国产在线观看| 亚洲天堂网中文字| 欧美精品一级二级| 亚洲一线二线三线久久久| 国产成人精品1024| 亚洲一区二区五区| 99久久免费精品| 亚洲精品国产高清久久伦理二区| 欧美色图12p| 亚洲丝袜美腿综合| 日韩综合一区二区| 欧洲精品视频在线观看| 亚洲色图视频网站| 91在线视频免费91| 一区二区在线观看视频| 色久优优欧美色久优优| 亚洲高清免费一级二级三级| 日韩欧美www| 欧美在线观看一区二区| 粉嫩在线一区二区三区视频| 爽好多水快深点欧美视频| 欧美激情综合五月色丁香小说| 色婷婷综合久久久久中文一区二区| 国内精品自线一区二区三区视频| 尤物在线观看一区| 亚洲综合成人在线| 香蕉成人伊视频在线观看| 中文文精品字幕一区二区| 亚洲va欧美va天堂v国产综合| 日韩精品一区二| 久久新电视剧免费观看| 在线免费观看一区| 亚洲日本中文字幕区| 欧美国产视频在线| 中文字幕中文乱码欧美一区二区| 爽好多水快深点欧美视频| 国产精品色哟哟网站| 欧美日韩日日骚| 色诱视频网站一区| 亚洲国产一区二区三区| 欧美日韩一卡二卡三卡| 在线综合视频播放| 一区二区三区精品久久久| 99久久99久久精品免费观看| 国产欧美日韩精品在线| 成人午夜免费av| 亚洲精品视频自拍| 欧美一区二区三区性视频| 久88久久88久久久| 国产精品欧美久久久久一区二区| 99久久免费国产| 亚洲国产wwwccc36天堂| 亚洲精品在线三区| 91在线视频播放| 免费观看在线综合| 亚洲欧洲国产日本综合| 欧美日韩精品一区二区三区| 国产资源精品在线观看| 自拍偷拍欧美精品| 日韩欧美一级二级| av亚洲精华国产精华精华| 蜜臀va亚洲va欧美va天堂| 中文字幕不卡的av| 欧美一卡二卡三卡四卡| 91亚洲精品一区二区乱码| 激情综合色播五月| 一区二区三区鲁丝不卡| 久久久不卡网国产精品二区| 精品视频一区二区不卡| av电影一区二区| 色综合天天狠狠| 久久午夜国产精品| a级精品国产片在线观看| 亚洲不卡一区二区三区| 中文字幕不卡在线观看| 精品乱码亚洲一区二区不卡| 91麻豆免费观看| 国产不卡一区视频| 麻豆精品一区二区三区| 午夜久久电影网| 一区二区三区在线播放| 国产精品三级在线观看| 久久日一线二线三线suv| 在线播放91灌醉迷j高跟美女| 色综合天天综合网国产成人综合天 | av亚洲产国偷v产偷v自拍| 一区二区免费在线|