首页 > 其他分享 >Golang基础--加锁与原子操作

Golang基础--加锁与原子操作

时间:2023-05-06 23:23:55浏览次数:34  
标签:count 加锁 -- goroutine Golang CountPlus time 操作 main

前言

  在实际项目开发中,有时会面临同一时刻将多个goroutine作用于同一个对象的情况,此时,他们之间会发生冲突,这种情况称为数据竞态问题。例如:

package main

import (
    "fmt"
    "time"
)

var count int

func main() {
    go CountPlus(10000)
    go CountPlus(10000)
    time.Sleep(time.Second)
    fmt.Println(count)
}
func CountPlus(times int) {
    for i := 0; i < times; i++ {
        count++
    }
}

  正常因该会返回20000,但是结果却不是。原因在于将两个goroutine作用于同一个count。

  解决方案:加锁

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var lock sync.Mutex

func main() {
    go CountPlus(10000)
    go CountPlus(10000)
    time.Sleep(time.Second)
    fmt.Println(count)
}
func CountPlus(times int) {
    for i := 0; i < times; i++ {
        lock.Lock()
        count++
        lock.Unlock()
    }
}

  声明Mutex类型的变量lock,并通过lock调用Lock()函数进行加锁,待操作完成后,在调用UnLock()解锁,在加锁和解锁函数之间的代码将受到保护,在同一时间仅有一个goroutine在执行受保护的代码。

  上述提及的Mutex为互斥锁,能很好的避免多个goroutine同时操作同一数据。

RWMutex读写互斥锁

  当某个goroutine获得读操作后,其他尝试进行读操作的goroutine也能正常获得锁,但是需要进行写操作的gioroutine会继续等待;

  当某个goroutine获得写操作的锁后,由于数据很可能发生改变,因此接下来的无论是读操作还是写操作都会继续排队等待。

  示例代码:

package main

import (
    "fmt"
    "sync"
    "time"
)

var countTest int
var locker sync.RWMutex

func main() {
    for i := 1; i <= 3; i++ {
        go Write(i)
    }
    for i := 1; i <= 3; i++ {
        go Read(i)
    }
    time.Sleep(10 * time.Second)
    fmt.Println("countTest的值为:", countTest)
}
func Read(i int) {
    fmt.Println("读操作:", i)
    locker.RLock()
    fmt.Println(i, "读countTest的值为:", countTest)
    time.Sleep(1 * time.Second)
    locker.RUnlock()
}
func Write(i int) {
    fmt.Println("写操作", i)
    locker.Lock()
    countTest++
    fmt.Println(i, "写countTest的值为:", countTest)
    time.Sleep(1 * time.Second)
    locker.Unlock()

}

这里解释一下代码的运行逻辑:程序一开始,就执行了写操作,其他goroutine只能等待其完成。但此时,后续的goroutine都开始执行,只不过运行到有锁的地方暂停了,因此可以看到大量“读操作”和“写操作”同时输出

  等待一秒后,3次读操作不会对数据发生更改,因此几乎同时完成操作

  再等待一秒后,2次写操作排队进行,然后完成操作

  最终,count被累加3次,值为3

标签:count,加锁,--,goroutine,Golang,CountPlus,time,操作,main
From: https://www.cnblogs.com/99kol/p/17378686.html

相关文章

  • golang hashmap
    packagemainimport("fmt")constHASH_BUCKET_SIZE=3//1023typehash_nodestruct{keyinterface{}valinterface{}next*hash_node}//hashbuckettosavenodeaddressvarhash_bucket[HASH_BUCKET_SIZE]*hash_nodefunc......
  • 2023-05-06:X轴上有一些机器人和工厂。给你一个整数数组robot,其中robot[i]是第i个机器
    2023-05-06:X轴上有一些机器人和工厂。给你一个整数数组robot,其中robot[i]是第i个机器人的位置再给你一个二维整数数组factory,其中factory[j]=[positionj,limitj]表示第j个工厂的位置在positionj,且第j个工厂最多可以修理limitj个机器人每个机器人所在的位置互不相......
  • Pycharm设置字体放大(缩小)快捷键
    一、设置放大字体ctrl+上滚轮设置-按键映射Keymap-搜索“increase”编辑器操作(EditorActions),增大字体大小(IncreaseFontSize)(双击),在弹出的对话框中选择添加鼠标快捷方式(AddMouseShortcut),在弹出的对话框中同时按住ctrl键和鼠标滚轮向上滑,点击OK完成设置二、设置缩小字体Ctr......
  • Rabbitmq介绍,安装,基于queue实现消费者生产者,基本使用,消息安全,持久化,闲置消费,发布订阅,
    内容详细Rabbmit介绍消息队列中间件概念很大,准确一些叫消息队列中间件消息队列中间件使用redis当作消息队列来用,blpop阻塞式弹出,实现队列,先进先出MQ,消息队列,MessageQueue是什么?消息队列就是基础数据结构中先进先出(队列)的一种数据机制,类比于生活中,买东西,需要排队,先排队的人......
  • NC51112 Stars in Your Window
    题目链接题目题目描述Fleetingtimedoesnotblurmymemoryofyou.Canitreallybe4yearssinceIfirstsawyou?Istillremember,vividly,onthebeautifulZhuhaiCampus,4yearsago,fromthemomentIsawyousmile,asyouwerewalkingoutoftheclassr......
  • python - pdf去除水印
    可以使用微信截图等工具查看需要删除水印的rgb值,1.pdf转为图片并去除水印importfitzfromitertoolsimportproductimportosfromfunctoolsimportcmp_to_keyfromtqdmimporttrange#打开pdf文件pdf=fitz.open('./test.pdf')defcheck_rgb(rgb):#判断水......
  • Medicine River ————-Learning journals 9
    Deardairy.                                20206MayHey,Harlan,longtimenosee.Howhaveyoubeenlately?I'vebeenquitebusylately.Ihopeyoudon'tblamemefornotcomingtoseeyo......
  • springboot整合springTask
    一、启动类开启task注解//springTask定时任务开启@EnableScheduling@SpringBootApplication@MapperScan("com.zhenghe.mapper")publicclassZhengheApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ZhengheApplication.class,a......
  • RUL预测常用数据集--C-MAPSS Dataset介绍
    C-MAPSS是针对航空发动机剩余寿命预测的数据集。该数据集由NASA(美国国家航空航天局)发布,包含了四个不同类型的航空发动机的传感器数据,以及相应的故障模式和剩余寿命数据,如表1所示。表1InformationoftheC-MAPSSdataset.DatasetFD001FD002FD003FD004Engineunit......
  • NC20545 [HEOI2012]采花
    题目链接题目题目描述萧芸斓是Z国的公主,平时的一大爱好是采花。今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花。花园足够大,容纳了\(n\)朵花,花有\(c\)种颜色(用整数\(1-c\)表示),且花是排成一排的,以便于公主采花。公主每次采花后会统计采到的花的颜色数,颜色数......