主线程,协程和互斥锁

package main
//路径上加上包的唯一标识 demo14,线程和协程,是go的核心
import (
	"fmt"
	"time"
	"sync"
)

// 需求:计算1-200之间所有数的阶乘,并且把各个数的阶乘放入map中。最后显示出来。使用协程完成。
var (
	map1 = make(map[int]int, 10) // 声明一个全局map
	lock sync.Mutex //互斥锁
)
func main() {
	for i := 1; i <= 200; i++ {
		// 启动200个协程
		go test(i)
	}
	//问题1 主线程休眠10秒钟,不休眠的话,因为主线程结束,协程也会结束,但是休眠的时间不确定
	
	time.Sleep(time.Second * 10)
	lock.Lock() // 读加锁 读的时候,可能会出现竞争,因为主线程不知道10秒钟协程是否执行完成;加锁可以避免这个问题
	for i, v := range map1 {
		fmt.Printf("map[%d]=%d\n", i, v)
	}
	lock.Unlock() // 读解锁
}
func test(n int){
	// 计算阶乘的函数
	res := 1
	for i := 1; i <= n; i++ {
		res = res * i
	}
	// 问题2,如果多个线程同时尝试写同一个数据结构(如Map),就可能发生数据竞争、数据不一致或其他并发问题
	lock.Lock() // 写,加锁
	map1[n] = res
	lock.Unlock() //写完,解锁
}

go build -race ./main.go之后执行main.exe,可以检查是否存在竞争问题

你可能感兴趣的:(go,golang)