首页 > 其他 > 详细

golang全局互斥锁解决资源竞争问题

时间:2021-06-10 11:26:28      阅读:15      评论:0      收藏:0      [点我收藏+]

一、需求

开启是个协程,计算1-10各个数的阶乘,并且把各个数的阶乘放入到map中,最后显示出来

二、代码实现

package main

import (
	"fmt"
	"time"
)

var myMap = make(map[int]int, 10)

func test(n int) {
	res := 1
	for i := 2; i <= n; i++ {
		res *= i
	}
	myMap[n] = res
}

func main() {
	for i := 1; i <= 20; i++ {
		go test(i)
	}
	time.Sleep(10 * time.Second)
	for key, value := range myMap {
		fmt.Printf("%d的阶乘为%d\n", key, value)
	}
}

输出结果:

fatal error: concurrent map writes
fatal error: concurrent map writes

分析:

因为可能存在同一时间有多个协程同时操作map,这就是资源竞争问题

三、-race参数

在运行某个程序时,如何知道是否存在资源竞争问题,方法很简单,在编译程序时,增加一个参数-race即可,如下图:
技术分享图片

技术分享图片

四、解决方案

使用全局变量加锁同步改进程序

  1. 因为没有对全局变量map加锁,因此会出现资源竞争问题,代码出现错误,concurrent map writes
  2. 解决方案,加入互斥锁
package main

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

var myMap = make(map[int]int, 10)

// 声明一个全局的互斥锁
// sync 是包: synchornized 同步
// Mutex : 是互斥
var lock sync.Mutex

// 计算n!,并将计算结果放入到myMap中
func test(n int) {
	res := 1
	for i := 2; i <= n; i++ {
		res *= i
	}
	// 加锁
	lock.Lock()
	myMap[n] = res
	// 解锁
	lock.Unlock()
}

func main() {
	// 开启多个10个协程共同工作
	for i := 1; i <= 10; i++ {
		go test(i)
	}
	time.Sleep(10 * time.Second)
	lock.Lock()
	for key, value := range myMap {
		fmt.Printf("%d的阶乘为%d\n", key, value)
	}
	lock.Unlock()
}

输出结果:

5的阶乘为120
1的阶乘为1
2的阶乘为2
7的阶乘为5040
6的阶乘为720
8的阶乘为40320
9的阶乘为362880
3的阶乘为6
4的阶乘为24
10的阶乘为3628800

golang全局互斥锁解决资源竞争问题

原文:https://www.cnblogs.com/adong2021/p/14869069.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!