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
发表评论