看到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 = 0 var condition = 0 func 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() } }
有疑问加站长微信联系(非本文作者)