Golang实现对map的并发读写的方法示例

 更新时间:2019年03月11日 10:13:52   作者:hackssssss  
这篇文章主要介绍了Golang实现对map的并发读写的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

在Golang多协程的情况下使用全局map时,如果不做线程同步,会出现panic的情况。

为了解决这个问题,通常有两种方式:

  • 第一种是最常见的使用互斥锁或者读写锁的方法;
  • 第二种是比较符合Golang特色的方法,启动单个协程对map进行读写,当其他协程需要读写map时,通过channel向这个协程发送信号即可。

写了一个模拟程序对map中的一项进行读或者写,后台一直运行的协程阻塞的接受读写信号,并对map进行操作,但是读操作的时候没想好怎么返回这个值。

后来想到用传引用的方式,定义结构体,第一个参数是读写的标志,第二个参数是读成功或者写成功后的值的channel,定义的channel中传结构体指针。

ps:以后验证一下效率。简单封装了一下:https://www.jb51.net/article/157620.htm

package main

import (
 "fmt"
 "strconv"
 "time"
)

type value struct {
 id int
 op int
 ret chan int
}
var dic map[int]int
var ch chan *value

func readAndWrite2Map() {
 for {
 select{
 case flag := <- ch:

  if flag.op > 0 {
  log.Printf("id: %v, op: %v, ret: %v", flag.id, flag.op, flag.op)
  dic[1] = flag.op
  flag.ret <- dic[1]
  } else if flag.op == 0 {
  log.Printf("id: %v, op: %v, ret: %v", flag.id, flag.op, dic[1])
  flag.ret <- dic[1]
  } else {
  return
  }
 }
 }
}


func out(flag, i, val int) {
 if flag == 0 {
 fmt.Println(strconv.Itoa(i) + "th goroutine read the value is ", val)
 } else {
 fmt.Println(strconv.Itoa(i)+"th goroutine write to the map ", val)
 }
}

func main() {
 dic = make(map[int]int)
 ch = make(chan *value)
 dic[1] = -1
 go readAndWrite2Map()
 for i := 0; i <= 5; i++ {
 if (i % 2) == 0 {
  go func(i int) {
   var tmp value
   for {
   tmp.op = 0
   ch <- &tmp
   out(0, i, <-tmp.ret)
   time.Sleep(time.Millisecond)
   }
  }(i)

 } else {
  go func(i int) {
   var tmp value
   for {
   tmp.op = i
   ch <- &tmp
   out(1, i, <-tmp.ret)
   time.Sleep(time.Millisecond)

   }
  }(i)
 }
 }
 time.Sleep(time.Second * 60)
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • go 代码格式化和风格开发者指南

    go 代码格式化和风格开发者指南

    这篇文章主要为大家介绍了go 代码格式化和风格开发者指南,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • golang 跳出for循环操作

    golang 跳出for循环操作

    这篇文章主要介绍了golang 跳出for循环操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • golang使用信号量热更新的实现示例

    golang使用信号量热更新的实现示例

    这篇文章主要介绍了golang使用信号量热更新的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • golang高并发系统限流策略漏桶和令牌桶算法源码剖析

    golang高并发系统限流策略漏桶和令牌桶算法源码剖析

    这篇文章主要介绍了golang高并发系统限流策略漏桶和令牌桶算法源码剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go 代码块作用域变量遮蔽问题解析

    Go 代码块作用域变量遮蔽问题解析

    这篇文章主要为大家介绍了Go 代码块作用域变量遮蔽问题解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • GoAdminGroup/go-admin的安装和运行的教程详解

    GoAdminGroup/go-admin的安装和运行的教程详解

    这篇文章主要介绍了GoAdminGroup/go-admin的安装和运行的教程详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Go每日一库之zap日志库的安装使用指南

    Go每日一库之zap日志库的安装使用指南

    这篇文章主要为大家介绍了Go每日一库之zap安装使用示例学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Golang unsafe包中的类型和函数详解

    Golang unsafe包中的类型和函数详解

    Golang中的unsafe包用于在运行时进行低级别的操作,这些操作通常是不安全的,因为可以打破Golang的类型安全性和内存安全性,使用 unsafe包的程序可能会影响可移植性和兼容性,接下来看下unsafe包中的类型和函数
    2023-08-08
  • Golang实现KV存储引擎实例探究

    Golang实现KV存储引擎实例探究

    这篇文章主要为大家介绍了Golang实现KV存储引擎实例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • golang使用RSA加密和解密的实现示例

    golang使用RSA加密和解密的实现示例

    在Golang中RSA加密和解密是一个常见的操作,本文主要介绍了golang使用RSA加密和解密的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2025-03-03

最新评论