golang中使用channel实现互斥锁
通过将带有一个缓冲区的channel作为一个桶,桶中的数据作为锁,每次要访问临界区的goroutine要首先拿到桶里的锁,以此来达到同步访问。
package main
import (
"fmt"
"runtime"
"sync"
)
var counter int
type Lock struct {
ch chan struct{}
}
func NewLock() *Lock {
return &Lock{
ch: make(chan struct{}, 1),
}
}
func (t *Lock) Lock() {
<-t.ch
}
func (t *Lock) Unlock() {
t.ch <- struct{}{}
}
func add(n int) {
tmp := counter
tmp += n
counter = tmp
}
func main() {
wg := sync.WaitGroup{}
wg.Add(100000)
t := NewLock()
t.ch <- struct{}{}
for i := 0; i < 100000; i++ {
go func(j int) {
t.Lock()
defer t.Unlock()
add(j)
wg.Done()
}(i)
}
wg.Wait()
fmt.Println(runtime.NumGoroutine())
fmt.Println(counter)
}