在Go语言中 sync.Cond 代表条件变量,但它需要配置锁才能有用.
c := sync.NewCond(&sync.RWMutex{})
之类.
它有三个函数: wait/signal/broadcast
望文知义,和Windows下的InitializeConditionVariable与WaitForSingleObject()之类,
及Linux下的pthread_cond_t等作用差不多.
var m Mutex
c := NewCond(&m)
或c := sync.NewCond(&sync.RWMutex{})
之类.
它有三个函数: wait/signal/broadcast
望文知义,和Windows下的InitializeConditionVariable与WaitForSingleObject()之类,
及Linux下的pthread_cond_t等作用差不多.
弄了两个例子:
/* 条件变量 Cond 例子 Author: xcl Date: 2015-11-29 */ package main import ( "fmt" "runtime" "sync" "time" ) func main() { runtime.GOMAXPROCS(4) test333() } func testCond() { c := sync.NewCond(&sync.Mutex{}) condition := false go func() { time.Sleep(time.Second * 1) c.L.Lock() fmt.Println("[1] 变更condition状态,并发出变更通知.") condition = true c.Signal() //c.Broadcast() fmt.Println("[1] 继续后续处理.") c.L.Unlock() }() c.L.Lock() fmt.Println("[2] condition..........1") for !condition { fmt.Println("[2] condition..........2") //等待Cond消息通知 c.Wait() fmt.Println("[2] condition..........3") } fmt.Println("[2] condition..........4") c.L.Unlock() fmt.Println("main end...") } /* testCond()运行结果: [2] condition..........1 [2] condition..........2 [1] 变更condition状态,并发出变更通知. [1] 继续后续处理. [2] condition..........3 [2] condition..........4 main end... */例二:
/* 条件变量 Cond 例子 Author: xcl Date: 2015-11-29 */ package main import ( "fmt" "runtime" "sync" "time" ) const MAX_CLIENTS = 3 func main() { runtime.GOMAXPROCS(4) testCond() } func testCond() { s := NewServer() go s.IOloop() time.Sleep(time.Second * 1) go func() { s.Release() }() go func() { s.Release() }() time.Sleep(time.Second * 1) s.Release() time.Sleep(time.Second * 1) fmt.Println("[testCond] end.") } type Server struct { clients uint64 cond *sync.Cond } func NewServer() *Server { s := &Server{} s.cond = sync.NewCond(&sync.Mutex{}) return s } func (s *Server) IOloop() { for { s.cond.L.Lock() for s.clients == MAX_CLIENTS { fmt.Println("[IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release()") s.cond.Wait() } s.cond.L.Unlock() s.clients++ fmt.Println("[IOloop] clients:", s.clients) } } func (s *Server) Release() { s.cond.L.Lock() s.clients-- fmt.Println("[Release] a clients:", s.clients) s.cond.Signal() fmt.Println("[Release] b clients:", s.clients) s.cond.L.Unlock() } /* 运行结果: [IOloop] clients: 1 [IOloop] clients: 2 [IOloop] clients: 3 [IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release() [Release] a clients: 2 [Release] b clients: 2 [Release] a clients: 1 [Release] b clients: 1 [IOloop] clients: 2 [IOloop] clients: 3 [IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release() [Release] a clients: 2 [Release] b clients: 2 [IOloop] clients: 3 [IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release() [testCond] end. */
对于条件变量和channl,知乎有个问答很精彩,可以看看: http://www.zhihu.com/question/27256570
另外 <<Go语言并发编程>>中也有个同一时间多个Goroutine分别进行对一个文件进行读写操作的例子也很精彩,直观。
噢,对了,附上C++11条件变量的使用例子:
// condition_variable example #include <iostream> // std::cout #include <thread> // std::thread #include <mutex> // std::mutex, std::unique_lock #include <condition_variable> // std::condition_variable std::mutex mtx; std::condition_variable cv; bool ready = false; void print_id (int id) { std::unique_lock<std::mutex> lck(mtx); while (!ready) cv.wait(lck); // ... std::cout << "thread " << id << '\n'; } void go() { std::unique_lock<std::mutex> lck(mtx); ready = true; cv.notify_all(); } int main () { std::thread threads[10]; // spawn 10 threads: for (int i=0; i<10; ++i) threads[i] = std::thread(print_id,i); std::cout << "10 threads ready to race...\n"; go(); // go! for (auto& th : threads) th.join(); return 0; }C++11例子来自: http://www.cplusplus.com/reference/condition_variable/condition_variable/
BLOG: http://blog.csdn.net/xcl168
有疑问加站长微信联系(非本文作者)