以下代码均运行通过
package main
import (
"fmt"
"runtime"
"sync"
"sync/atomic"
)
//计数器(竞争资源)
var counter int64
//wg用来等待程序完成
var wg sync.WaitGroup
//互斥锁
var mutex sync.Mutex
func main() {
//分配一个逻辑处理器给调度器使用
runtime.GOMAXPROCS(1)
//引用计数+2,便是要等待两个goroutine
wg.Add(2)
fmt.Println("Start Gorountines")
var cse = 0 //可根据要求更改cse值,查看相应的运行就结果
//创建两个gorountine
switch cse {
case 0: //竞争状态
go incCounterA(1)
go incCounterA(2)
case 1: //原子函数
go incCounterB(1)
go incCounterB(2)
case 2: //互斥锁
go incCounterC(1)
go incCounterC(2)
}
//等待goroutine结束
fmt.Println("Wait To Finish")
wg.Wait()
fmt.Println("Terminating Program")
}
func incCounterA(cntId int) {
defer wg.Done()
for count := 0; count < 2; count++ {
//捕获counter的值
value := counter
fmt.Printf("ID=%d_A cnter=%d\n", cntId, counter)
//当前goroutine从线程退出,并放回到队列
runtime.Gosched()
//增加本地value变量的值
value++
counter = value
fmt.Printf("ID=%d_B cnter=%d\n", cntId, counter)
}
}
func incCounterB(cntId int) {
defer wg.Done()
for count := 0; count < 2; count++ {
fmt.Printf("ID=%d_A cnter=%d\n", cntId, counter)
atomic.AddInt64(&counter, 1)
//当前goroutine从线程退出,并放回到队列
runtime.Gosched()
fmt.Printf("ID=%d_B cnter=%d\n", cntId, counter)
}
}
func incCounterC(cntId int) {
defer wg.Done()
for count := 0; count < 2; count++ {
//同一时刻,只允许一个goroutine进入临界区
mutex.Lock()
{
//捕获counter的值
value := counter
fmt.Printf("ID=%d_A cnter=%d\n", cntId, counter)
//当前goroutine从线程退出,并放回到队列
runtime.Gosched()
//增加本地value变量的值
value++
counter = value
fmt.Printf("ID=%d_B cnter=%d\n", cntId, counter)
}
//释放锁,允许其他等待的gorutine进入临界区
mutex.Unlock()
}
}