這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
看到golang 標準庫 sync package 提供了傳統的mutex, once, cond, rwmutex 等基於共用記憶體的同步原語,就想寫個代碼實驗一下。
type Cond struct { // L is held while observing or changing the condition L Locker // contains filtered or unexported fields}
Cond 結構包含一個可匯出的Locker 對象
func NewCond(l Locker) *Cond
NewCond 函數 接受一個實現Locker 介面的對象, 返回一個指向Cond 的指標; pthread_cond_t 對應於此
func (c *Cond) Broadcast()
Brocast 喚醒所有在這個cond 對象上等待的 goroutine; pthread_cond_brocast() 對應於此
func (c *Cond) Signal()
Signal 喚醒一個再此cond 對象上等待的goroutine; pthread_cond_signal() 對應於此
type Mutex struct { // contains filtered or unexported fields }
func (m *Mutex) Lock()
func (m *Mutex) Unlock()
Mutex 擁有Lock,Unlock 方法, 所以實現了
type Locker interface { Lock() Unlock()}
#include <stdio.h>#include <pthread.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;int condition = 0;int count = 0;int consume( void ){ while( 1 ) { pthread_mutex_lock( &mutex ); while( condition == 0 ) pthread_cond_wait( &cond, &mutex ); printf( "Consumed %d\n", count ); condition = 0; pthread_cond_signal( &cond ); pthread_mutex_unlock( &mutex ); } return( 0 );}void* produce( void * arg ){ while( 1 ) { pthread_mutex_lock( &mutex ); while( condition == 1 ) pthread_cond_wait( &cond, &mutex ); printf( "Produced %d\n", count++ ); condition = 1; pthread_cond_signal( &cond ); pthread_mutex_unlock( &mutex ); } return( 0 );}int main( void ){ pthread_t thr; pthread_create( &thr, NULL, &produce, NULL ); return consume();}
接著等價的golang 實現:
package main import ( "fmt" "sync")var count = 0var condition = 0func main(){ lock := new(sync.Mutex) cond := sync.NewCond(lock) go func (){ for { lock.Lock() for condition == 0 { cond.Wait() } fmt.Printf("Consumed %d\n", count ) condition = 0 cond.Signal() lock.Unlock() } }() for { lock.Lock() for condition == 1 { cond.Wait() } fmt.Printf("Produced %d\n", count ) count++ condition = 1 cond.Signal() lock.Unlock() }}