funcmain() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) //添加请求goroutine的数量,add(n),counter+=n s gofunc() { //每执行完一个goroutine,counter -= 1。 //当计数器counter为0时通过信号量调用runtime_Semrelease唤醒waiter线程 defer wg.Done() fmt.Println("hello") }() } wg.Wait() //waiter++,通过信号量runtime_Semacquire(semap)阻塞当前goroutine }
二、map
三、mutex
1 2 3 4
type Mutex struct { state int32//存储互斥锁的状态,state = 0即是未加锁 sema uint32//信号量,主要用作等待队列 }
四、RWMutex
适用于读多于写的场景
1 2 3 4 5 6 7
type RWMutex struct { w Mutex // held if there are pending writers 复用互斥锁 writerSem uint32// semaphore for writers to wait for completing readers 写操作的阻塞和唤醒的信号量 readerSem uint32// semaphore for readers to wait for completing writers 读操作的阻塞和唤醒的信号量 readerCount int32// number of pending readers 正在执行读的goroutine数量 readerWait int32// number of departing readers 被阻塞的准备读的goroutine(groutine获取了写锁,若后面有goroutine要读,那么这些goroutine会被阻塞) }