您的位置:首页 > 编程语言 > Go语言

Go语言条件变量的两个例子

2015-11-29 19:09 393 查看
      在Go语言中 sync.Cond 代表条件变量,但它需要配置锁才能有用.
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息