婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > golang線程安全的map實現

golang線程安全的map實現

熱門標簽:高德地圖標注口訣 江西轉化率高的羿智云外呼系統 中國地圖標注省會高清 學海導航地圖標注 南通如皋申請開通400電話 地圖標注的汽車標 西部云谷一期地圖標注 浙江高速公路地圖標注 廣州呼叫中心外呼系統

網上找的協程安全的map都是用互斥鎖或者讀寫鎖實現的,這里用單個協程來實現下,即所有的增刪查改操作都集成到一個goroutine中,這樣肯定不會出現多線程并發訪問的問題。

基本思路是后臺啟動一個長期運行的goroutine,阻塞的接受自己channel中的請求req,req分為不同的請求,比如讀key,寫key等,然后在這個goroutine中進行各種操作。

例: Get方法向readSig(channel)中發送一條請求。請求是readReq的指針,當run方法接收到信號時,讀取底層map,將值寫入readReq的value中(value是個channel),Get方法阻塞的接收value,接收到就返回value。

ps:花了兩個多小時寫完,只是簡單的做了測試,沒有深入測試,另外性能也沒有測過,以后有空會深入測試一下正確性以及相比加鎖的寫法其性能如何。

package util
 
type smap struct {
 m      map[interface{}]interface{}
 readSig   chan *readReq
 writeSig   chan *writeReq
 lenSig    chan *lenReq
 terminateSig chan bool
 delSig    chan *delReq
 scanSig   chan *scanReq
}
 
type readReq struct {
 key  interface{}
 value interface{}
 ok  chan bool
}
 
type writeReq struct {
 key  interface{}
 value interface{}
 ok  chan bool
}
 
type lenReq struct {
 len chan int
}
 
type delReq struct {
 key interface{}
 ok chan bool
}
 
type scanReq struct {
 do     func(interface{}, interface{})
 doWithBreak func(interface{}, interface{}) bool
 brea    int
 done    chan bool
}
// NewSmap returns an instance of the pointer of safemap
func NewSmap() *smap {
 var mp smap
 mp.m = make(map[interface{}]interface{})
 mp.readSig = make(chan *readReq)
 mp.writeSig = make(chan *writeReq)
 mp.lenSig = make(chan *lenReq)
 mp.delSig = make(chan *delReq)
 mp.scanSig = make(chan *scanReq)
 go mp.run()
 return mp
}
 
//background function to operate map in one goroutine
//this can ensure that the map is Concurrent security.
func (s *smap) run() {
 for {
 select {
 case read := -s.readSig:
  if value, ok := s.m[read.key]; ok {
  read.value = value
  read.ok - true
  } else {
  read.ok - false
  }
 case write := -s.writeSig:
  s.m[write.key] = write.value
  write.ok - true
 case l := -s.lenSig:
  l.len - len(s.m)
 case sc := -s.scanSig:
  if sc.brea == 0 {
  for k, v := range s.m {
   sc.do(k, v)
  }
  } else {
  for k, v := range s.m {
   ret := sc.doWithBreak(k, v)
   if ret {
   break
   }
  }
  }
  sc.done - true
 case d := -s.delSig:
  delete(s.m, d.key)
  d.ok - true
 case -s.terminateSig:
  return
 }
 }
}
 
//Get returns the value of key which provided.
//if the key not found in map, ok will be false.
func (s *smap) Get(key interface{}) (interface{}, bool) {
 req := readReq{
 key: key,
 ok: make(chan bool),
 }
 s.readSig - req
 ok := -req.ok
 return req.value, ok
}
 
//Set set the key and value to map
//ok returns true indicates that key and value is successfully added to map
func (s *smap) Set(key interface{}, value interface{}) bool {
 req := writeReq{
 key:  key,
 value: value,
 ok:  make(chan bool),
 }
 s.writeSig - req
 return -req.ok //TODO 暫時先是同步的,異步的可能存在使用方面的問題。
}
 
//Clear clears all the key and value in map.
func (s *smap) Clear() {
 s.m = make(map[interface{}]interface{})
}
 
//Size returns the size of map.
func (s *smap) Size() int {
 req := lenReq{
 len: make(chan int),
 }
 s.lenSig - req
 return -req.len
}
 
//terminate s.Run function. this function is usually called for debug.
//after this do NOT use smap again, because it can make your program block.
func (s *smap) TerminateBackGoroutine() {
 s.terminateSig - true
}
 
//Del delete the key in map
func (s *smap) Del(key interface{}) bool {
 req := delReq{
 key: key,
 ok: make(chan bool),
 }
 s.delSig - req
 return -req.ok
}
 
//scan the map. do is a function which operate all of the key and value in map
func (s *smap) EachItem(do func(interface{}, interface{})) {
 req := scanReq{
 do:  do,
 brea: 0,
 done: make(chan bool),
 }
 s.scanSig - req
 -req.done
}
 
//scan the map util function 'do' returns true. do is a function which operate all of the key and value in map
func (s *smap) EachItemBreak(do func(interface{}, interface{}) bool, condition bool) {
 req := scanReq{
 doWithBreak: do,
 brea:    1,
 done:    make(chan bool),
 }
 s.scanSig - req
 -req.done
}
 
//Exists checks whether the key which provided is exists in map
func (s *smap) Exists(key interface{}) bool {
 if _,found := s.Get(key); found {
 return true
 }
 return false
}

github地址:https://github.com/hackssssss/safemap

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • Golang Map實現賦值和擴容的示例代碼
  • golang中range在slice和map遍歷中的注意事項
  • golang 并發安全Map以及分段鎖的實現方法
  • Golang實現對map的并發讀寫的方法示例
  • golang中sync.Map并發創建、讀取問題實戰記錄
  • golang如何實現mapreduce單進程版本詳解
  • Golang map如何生成有序的json數據詳解
  • golang針對map的判斷,刪除操作示例
  • 理解Golang中的數組(array)、切片(slice)和map
  • Golang 使用map需要注意的幾個點

標簽:常州 東營 吐魯番 德宏 曲靖 貴州 保定 許昌

巨人網絡通訊聲明:本文標題《golang線程安全的map實現》,本文關鍵詞  golang,線程,安全,的,map,實現,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《golang線程安全的map實現》相關的同類信息!
  • 本頁收集關于golang線程安全的map實現的相關信息資訊供網民參考!
  • 企业400电话

    智能AI客服机器人
    15000

    在线订购

    合计11份范本:公司章程+合伙协议+出资协议+合作协议+股权转让协议+增资扩股协议+股权激励+股东会决议+董事会决议

    推薦文章
    主站蜘蛛池模板: 荔波县| 南陵县| 永修县| 乌兰县| 五河县| 云林县| 拉萨市| 名山县| 眉山市| 平潭县| 梁河县| 武义县| 寻乌县| 邹城市| 穆棱市| 什邡市| 图片| 饶阳县| 泗洪县| 平泉县| 萨迦县| 仁寿县| 龙口市| 西吉县| 资中县| 昌邑市| 合作市| 大理市| 六安市| 乐平市| 隆安县| 遵义市| 安国市| 西峡县| 永吉县| 天峻县| 习水县| 宝鸡市| 静安区| 遵义县| 绥中县|