结论:利用缓冲大小为 1 的 channel来实现互斥锁mutex。实现原理:如果缓冲满了,发送(写入)到通道时将会阻塞;如果通道清空,发送时就会解除阻塞。
package main
import (
"errors"
"fmt"
"os"
"sync"
)
var lock sync.Mutex
/**
【通过channel管道实现Mutex互斥锁】
缓冲大小为 1 的 channel 具有如下的特性:如果缓冲满了,发送(写入)到通道时将会阻塞;如果通道清空,发送时就会解除阻塞。
显然,这种 channel 的阻塞特性是可取的,与互斥锁的特性做个对比:
缓冲满时 <--> 上锁
缓冲腾空 <--> 解锁
**/
func main() {
file, err := os.Create("record3.txt")
defer func() {
if err := recover(); err != nil {
fmt.Printf("Error encounter: %w", err)
}
file.Close()
}()
if err != nil {
panic(errors.New("Cannot create/open file"))
}
ss := []string{ //string slice literals
"James",
"Avery",
"Peter",
"John",
"Beau",
}
chanLock := make(chan int, 1) //1
var wg sync.WaitGroup // WaitGroup 来保证子 goroutine 完成任务之前,主协程不会退出。
for _, str := range ss { //2
wg.Add(1) //
go func(aString string) {
// lock.Lock() 互斥锁的实现方式
chanLock <- 1 //3
for i := 0; i < 1000; i++ {
file.WriteString(aString + "\n")
}
// lock.Unlock()
<-chanLock //4
wg.Done() //5
}(str) //pass by value
}
wg.Wait()
}