2020/06/11
- 今日簡單認識一下 Package sync
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var ticket int = 10
var mutex sync.Mutex // 建立互斥鎖
var wg sync.WaitGroup // 建立同步等待組
var rwMutex sync.RWMutex // 建立讀寫鎖
func main() {
wg.Add(7)
// 臨界資源問題,會出現超賣的現象 (互斥鎖)
go getRich("脫貧機會1")
go getRich("脫貧機會2")
go getRich("脫貧機會3")
// 讀寫鎖
go writeData(1)
go readData(1)
go writeData(2)
go readData(2)
wg.Wait() // main 等待
fmt.Println("程式結束")
}
func getRich(task string) {
rand.Seed(time.Now().UnixNano()) // 生成隨機數量
defer wg.Done()
for {
mutex.Lock() // 上鎖之後,只能有一個 goroutine 執行
if ticket > 0 {
time.Sleep(time.Duration(rand.Intn(1000)) * time.Microsecond)
fmt.Println("脫貧人口在減少:", ticket)
ticket--
} else {
mutex.Unlock() // 解鎖
fmt.Println(task, "用完了,你註定是窮人了!")
break
}
mutex.Unlock() // 使用互斥鎖的時候操作結束之後,一定要解鎖
}
}
// 可以多個 goroutine 同時讀
func readData(i int) {
defer wg.Done()
fmt.Println(i, "read start ...")
rwMutex.RLock() // 讀操作上鎖
fmt.Println(i, "reading...")
time.Sleep(3 * time.Second)
rwMutex.RUnlock() // 讀操作解鎖
fmt.Println(i, "read over ...")
}
// 寫的時候加鎖,不能讀也不能寫
func writeData(i int) {
defer wg.Done()
fmt.Println(i, "write start ...")
rwMutex.Lock()
fmt.Println(i, "writing ...")
time.Sleep(3 * time.Second)
rwMutex.Unlock() // 寫操作解鎖
fmt.Println(i, "write over ...")
}
順便佛系一下用 go 做做 leetcode 的練習題同步到了 GitHub 大家也可以看看。
一步一個腳印,穩紮穩打,重新出發!從基本的 Golang Packages 記憶開始,堅持 ing!
本作品採用《CC 協議》,轉載必須註明作者和本文連結