在go协程中共享资源需要加锁处理

 Golang  2023-04-14  admin  392  529

在go协程中共享资源需要加锁处理

package main

import (
	"fmt"
	"sync"
)

// 创建一个互斥锁
var mutex = &sync.Mutex{}

// 定义一个共享资源
var sharedResource = 0

// 定义一个等待组
var wg = sync.WaitGroup{}

// 定义一个函数,用于对共享资源进行加操作
func increment(i int) {
	// 加锁
	mutex.Lock()
	// 在函数结束时解锁
	defer mutex.Unlock()
	// 对共享资源进行加操作
	sharedResource++
	// 打印共享资源的值
	fmt.Println("协程id:", i, " 共享资源值:", sharedResource)
	//fmt.Println(sharedResource)
	// 通知等待组,该函数已经执行完毕
	wg.Done()
}

func main() {
	// 添加等待组的计数器
	wg.Add(20)
	// 启动两个 goroutine,对共享资源进行加操作
	//go increment()
	//go increment()

	for i := 0; i < 20; i++ {
		go increment(i)
	}
	// 等待两个 goroutine 执行完毕
	wg.Wait()
}


//不加锁

//协程id: 3  共享资源值: 1

//协程id: 19  共享资源值: 3

//协程id: 4  共享资源值: 4

//协程id: 5  共享资源值: 5

//协程id: 6  共享资源值: 6

//协程id: 7  共享资源值: 7

//协程id: 8  共享资源值: 8

//协程id: 9  共享资源值: 9

//协程id: 10  共享资源值: 10

//协程id: 11  共享资源值: 11

//协程id: 12  共享资源值: 12

//协程id: 13  共享资源值: 13

//协程id: 14  共享资源值: 14

//协程id: 15  共享资源值: 15

//协程id: 16  共享资源值: 16

//协程id: 17  共享资源值: 17

//协程id: 18  共享资源值: 18

//协程id: 0  共享资源值: 19

//协程id: 2  共享资源值: 20

//协程id: 1  共享资源值: 2


//不加锁

//协程id: 0  共享资源值: 1

//协程id: 4  共享资源值: 2

//协程id: 3  共享资源值: 3

//协程id: 11  共享资源值: 4

//协程id: 19  共享资源值: 5

//协程id: 5  共享资源值: 6

//协程id: 12  共享资源值: 7

//协程id: 6  共享资源值: 8

//协程id: 13  共享资源值: 9

//协程id: 7  共享资源值: 10

//协程id: 14  共享资源值: 11

//协程id: 15  共享资源值: 13

//协程id: 8  共享资源值: 12

//协程id: 9  共享资源值: 15

//协程id: 10  共享资源值: 16

//协程id: 16  共享资源值: 14

//协程id: 17  共享资源值: 17

//协程id: 1  共享资源值: 18

//协程id: 18  共享资源值: 17

//协程id: 2  共享资源值: 19


// 通过 race 测试

//协程id: 0  共享资源值: 1

//协程id: 2  共享资源值: 2

//==================

//WARNING: DATA RACE

//Read at 0x000000621da8 by goroutine 8:

//  main.increment()

//      F:/MyGo/study/Mutex/demo.go:24 +0x35

//  main.main.func1()

//      F:/MyGo/study/Mutex/demo.go:40 +0x39

//

//Previous write at 0x000000621da8 by goroutine 7:

//  main.increment()

//      F:/MyGo/study/Mutex/demo.go:24 +0x4d

//  main.main.func1()

//      F:/MyGo/study/Mutex/demo.go:40 +0x39

//

//Goroutine 8 (running) created at:

//  main.main()

//      F:/MyGo/study/Mutex/demo.go:40 +0x84

//

//Goroutine 7 (finished) created at:

//  main.main()

//      F:/MyGo/study/Mutex/demo.go:40 +0x84

//==================

//协程id: 1  共享资源值: 3

//协程id: 3  共享资源值: 4

//协程id: 4  共享资源值: 5

//协程id: 5  共享资源值: 6

//协程id: 6  共享资源值: 7

//协程id: 7  共享资源值: 8

//协程id: 9  共享资源值: 10

//协程id: 8  共享资源值: 9

//协程id: 11  共享资源值: 11

//协程id: 10  共享资源值: 12

//协程id: 12  共享资源值: 13

//协程id: 13  共享资源值: 14

//协程id: 14  共享资源值: 15

//协程id: 15  共享资源值: 16

//协程id: 16  共享资源值: 17

//协程id: 17  共享资源值: 18

//协程id: 18  共享资源值: 19

//协程id: 19  共享资源值: 20

//Found 1 data race(s)

//exit status 66


//加锁

//协程id: 0  共享资源值: 1

//协程id: 3  共享资源值: 2

//协程id: 1  共享资源值: 3

//协程id: 2  共享资源值: 4

//协程id: 4  共享资源值: 5

//协程id: 5  共享资源值: 6

//协程id: 6  共享资源值: 7

//协程id: 7  共享资源值: 8

//协程id: 15  共享资源值: 9

//协程id: 17  共享资源值: 10

//协程id: 8  共享资源值: 11

//协程id: 9  共享资源值: 12

//协程id: 10  共享资源值: 13

//协程id: 11  共享资源值: 14

//协程id: 12  共享资源值: 15

//协程id: 13  共享资源值: 16

//协程id: 14  共享资源值: 17

//协程id: 16  共享资源值: 18

//协程id: 18  共享资源值: 19

//协程id: 19  共享资源值: 20


如果文章对您有帮助,点击下方的广告,支持一下作者吧!

相关推荐


go WaitGroup 的使用方法

在 Go 中,sync 包下的 WaitGroup 能有助于我们控制协程之间的同步。当需要等待一组协程都执行完各自任务后,才能继续后续逻辑。这种场景,就非常适合使用它。WaitGroup 提供三个 API。Add(delta int) 函数提供了 WaitGroup 的任务计数,delta 的值可以为正也可以为负,通常在添加任务时使用。Done() 函数其实就是 Add(-1),在任务完成时调用。

go 协程管理及传参处理

Go语言中的goroutine虽然相对于系统线程来说比较轻量级(初始栈大小仅2KB),(并且支持动态扩容),而正常采用java,c++等语言启用的线程一般都是内核态的占用的内存资源一般在4m左右,而假设我们的服务器CPU内存为4G,那么很明显才用的内核态线程的并发总数量也就是1024个,相反查看一下Go语言的协程则可以达到4*1024*1024/2=200w.这么一看就明白了为什么Go语言天生支持

go 协程示例:获取指定范围的质数

go 协程示例:获取指定范围的质数

Go 协程计算圆周率

Go 协程计算圆周率//Concurrentcomputationofpi. //Seehttps://goo.gl/la6Kli. // //ThisdemonstratesGo&#39;sabilitytohandle //largenumbersofconcurrentprocesses. //Itisanunreasonablewaytocalculatepi. package