Test code:
package main import ( "time" "fmt" "flag" ) var unbufferedChannel = flag.Bool("u", true, "unbuffered channel") func main() { flag.Parse() count := 0 if *unbufferedChannel { count = 0 fmt.Printf("unbuffered channel\n") } else { count = 1 fmt.Printf("buffered channel\n") } c := make(chan string, count) go func() { doInFunc(1) c <- "done" fmt.Printf("%v func return\n", time.LocalTime()) }() doInMain(2) <-c fmt.Printf("%v main return\n", time.LocalTime()) } func doInMain(sec int) { fmt.Printf("%v begin doInMain()\n", time.LocalTime()) time.Sleep((int64)(sec*1e9)) fmt.Printf("%v end doInMain()\n", time.LocalTime()) } func doInFunc(sec int) { fmt.Printf("%v begin doInFunc()\n", time.LocalTime()) time.Sleep((int64)(sec*1e9)) fmt.Printf("%v end doInFunc()\n", time.LocalTime()) }Run Result:
root001@ubuntu001:~/foolbear$ ./testch.out -u=false buffered channel Thu Feb 4 12:55:24 CST 2010 begin doInMain() Thu Feb 4 12:55:24 CST 2010 begin doInFunc() Thu Feb 4 12:55:25 CST 2010 end doInFunc() Thu Feb 4 12:55:25 CST 2010 func return Thu Feb 4 12:55:26 CST 2010 end doInMain() Thu Feb 4 12:55:26 CST 2010 main return
root001@ubuntu001:~/foolbear$ ./testch.out unbuffered channel Thu Feb 4 13:03:24 CST 2010 begin doInMain() Thu Feb 4 13:03:24 CST 2010 begin doInFunc() Thu Feb 4 13:03:25 CST 2010 end doInFunc() Thu Feb 4 13:03:26 CST 2010 end doInMain() Thu Feb 4 13:03:26 CST 2010 main return Thu Feb 4 13:03:26 CST 2010 func return注意上面测试结果的输出时序,对比 buffered/unbuffered channel 的不同逻辑。
总结:
Receivers always block until there is data to receive. If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
Case two:
Test code:
package main import ( "time" "fmt" ) const ( requestCount = 4 concurrentCount = 2 ) var sem = make(chan int, concurrentCount) var done = make(chan int, requestCount) func handle(index int) { sem <- 1 fmt.Printf("[%d]%v job begin\n", index, time.LocalTime()) time.Sleep((int64)(2*1e9)) <- sem done <- 0 fmt.Printf("[%d]%v handle return\n", index, time.LocalTime()) } func Serve() { for index := 0; index < requestCount; index ++ { go handle(index) } for index := 0; index < requestCount; index ++ { <- done } } func main() { Serve() fmt.Printf("%v main return, 全部结束了\n", time.LocalTime()) }Run Result:
[0]Thu Feb 4 16:46:09 CST 2010 job begin [1]Thu Feb 4 16:46:09 CST 2010 job begin [0]Thu Feb 4 16:46:11 CST 2010 handle return [1]Thu Feb 4 16:46:11 CST 2010 handle return [2]Thu Feb 4 16:46:11 CST 2010 job begin [3]Thu Feb 4 16:46:11 CST 2010 job begin [2]Thu Feb 4 16:46:13 CST 2010 handle return [3]Thu Feb 4 16:46:13 CST 2010 handle return Thu Feb 4 16:46:13 CST 2010 main return, 全部结束了总结:
A buffered channel can be used like a semaphore, for instance to limit throughput. In this example, incoming requests are passed to handle, which sends a value into the channel, processes the request, and then receives a value from the channel. The capacity of the channel buffer limits the number of simultaneous calls to process.FYI:
1 条评论 :
Hi there to every one, the contents existing at this
web page are truly remarkable for people experience, well, keep up the good work fellows.
Take a look at my web site ... Cheap Louis Vuitton
发表评论