package mainimport ( "fmt")func main() { fmt.Println("Begin doing something!") ch := make(chan int) go func() { fmt.Println("Doing something…") ch <- 22 //close(ch) }() <-ch //此处将被阻塞,直到ch被关闭 或 有值可以取出 fmt.Println("Done!")}
package mainimport "fmt"func worker(start chan bool, index int) { <-start // 从start中取出数据后,调用20行的case语句 fmt.Println("This is Worker:", index)}func main() { start := make(chan bool) for i := 1; i <= 10; i++ { go worker(start, i) } //给start赋值10次,让worker方法执行10次 for i := 1; i <= 10; i++ { start <- true //给start赋值一次,便执行worker函数一次 } v := 1 //select 被一直阻塞直到start中数据被取出 select { //deadlock we expected case <-start: fmt.Print(v) v++ }}
for { select { case x := <- somechan: // … 使用x进行一些操作 case y, ok := <- someOtherchan: // … 使用y进行一些操作, // 检查ok值判断someOtherchan是否已经关闭 case outputChan <- z: // … z值被成功发送到Channel上时 default: // … 上面case均无法通信时,执行此分支 }}
package mainimport ( "fmt" "time")func worker(die chan bool, index int) { fmt.Println("Begin: This is Worker:", index) for { select { //case xx: //做事的分支 case <-die: //到这里就被阻塞,运行main中的close后输出 done fmt.Println("Done: This is Worker:", index) return } }}func main() { die := make(chan bool) for i := 1; i <= 10; i++ { go worker(die, i) } time.Sleep(time.Second * 5) close(die) select {} //deadlock we expected}
package mainimport ( "fmt" //"time")func worker(die chan bool) { fmt.Println("Begin: This is Worker") for { select { //case xx: //做事的分支 case <-die: //这里等待27行的赋值语句,如果没有赋值,一直阻塞 fmt.Println("Done: This is Worker") die <- true return } }}func main() { die := make(chan bool) go worker(die) die <- true istrue := <-die //这里等待16行的赋值,赋值完毕后程序继续执行 fmt.Println("Worker goroutine has been terminated", istrue)}
package mainimport "fmt"func main() { cb := make(chan bool) close(cb) //当cb被关闭后,所有的取值操作将不会被阻塞 x := <-cb fmt.Printf("%#v\n", x) x, ok := <-cb fmt.Printf("%#v %#v\n", x, ok) ci := make(chan int) close(ci) y := <-ci //即使ci被关闭,照样可以从ci中取数据,取得0 fmt.Printf("%#v\n", y) cb <- true }
false
false false
0
panic: send on closed channel
19行将报异常
可以看到在一个已经close的unbuffered channel上执行读操作,回返回channel对应类型的零值,比如bool型channel返回false,int型channel返回0。但向close的channel写则会触发panic。不过无论读写都不会导致阻塞。
package mainimport "fmt"func main() { c := make(chan int, 3) c <- 15 c <- 34 c <- 65 close(c) fmt.Printf("%d\n", <-c) //channel被关闭后,照样可以从channel中取出数据,只是不能向其中写数据 fmt.Printf("%d\n", <-c) fmt.Printf("%d\n", <-c) fmt.Printf("%d\n", <-c) //当channel中数据全部被取出时,将输出0 c <- 1}
package mainimport "fmt"func generator(strings chan string) { strings <- "Five hour‘s New York jet lag" strings <- "and Cayce Pollard wakes in Camden Town" strings <- "to the dire and ever-decreasing circles" strings <- "of disrupted circadian rhythm." close(strings)}func main() { strings := make(chan string) go generator(strings) for s := range strings { fmt.Printf("%s\n", s) //这里的s 相当于 <- strings,只有赋值之后才能读取到,否则一直阻塞 } fmt.Printf("\n")}
package mainimport "fmt"func newUniqueIDService() <-chan string { id := make(chan string) go func() { var counter int64 = 0 for { id <- fmt.Sprintf("%x", counter) counter += 1 } }() return id}func main() { id := newUniqueIDService() for i := 0; i < 10; i++ { fmt.Println(<-id) //被阻塞,直到id被赋值 }}
package main
import "fmt"
func newUniqueIDService() <-chan string {
id := make(chan string)
go func() {
var counter int64 = 0
for {
id <- fmt.Sprintf("%x", counter)
counter += 1
}
}()
return id
func main() {
id := newUniqueIDService()
for i := 0; i < 10; i++ {
fmt.Println(<-id) //被阻塞,直到id被赋值
idle := make(chan []byte, 5) //用一个带缓冲的channel构造一个简单的队列 select { case <-idle: //尝试从idle队列中读取 fmt.Println("读取") default: //队列空,分配一个新的buffer fmt.Println("写入") }
idle := make(chan []byte, 5) //用一个带缓冲的channel构造一个简单的队列
select {
case <-idle:
//尝试从idle队列中读取
fmt.Println("读取")
default: //队列空,分配一个新的buffer
fmt.Println("写入")
package mainimport ( "fmt")func main() { idle := make(chan []int, 10) //用一个带缓冲的channel构造一个简单的队列 var b = []int{2, 1} select { case idle <- b: //尝试向队列中插入一个buffer fmt.Println(idle) default: //队列满? println("队列满") }}
import (
"fmt"
)
idle := make(chan []int, 10) //用一个带缓冲的channel构造一个简单的队列
var b = []int{2, 1}
case idle <- b: //尝试向队列中插入一个buffer
fmt.Println(idle)
default: //队列满?
println("队列满")
package mainfunc main() { var c chan int c <- 1}
var c chan int
c <- 1
package mainimport "fmt"import "time"func main() { var c1, c2 chan int = make(chan int), make(chan int) go func() { time.Sleep(time.Second * 5) c1 <- 5 close(c1) }() go func() { time.Sleep(time.Second * 7) c2 <- 7 close(c2) }() for { select { case x := <-c1: //在等待5s后,把值取出,如果close(c1)那么,将一直输出0 fmt.Println(x) case x := <-c2: //在等待7s后,输出c2的值并退出 fmt.Println(x) return } } fmt.Println("over")}
import "time"
var c1, c2 chan int = make(chan int), make(chan int)
time.Sleep(time.Second * 5)
c1 <- 5
close(c1)
time.Sleep(time.Second * 7)
c2 <- 7
close(c2)
case x := <-c1: //在等待5s后,把值取出,如果close(c1)那么,将一直输出0
fmt.Println(x)
case x := <-c2: //在等待7s后,输出c2的值并退出
return
fmt.Println("over")
package mainimport "fmt"import "time"func main() { var c1, c2 chan int = make(chan int), make(chan int) go func() { time.Sleep(time.Second * 5) c1 <- 5 close(c1) }() go func() { time.Sleep(time.Second * 7) c2 <- 7 close(c2) }() for { select { case x, ok := <-c1: //如果c1未被关闭,则输出x,如果x关闭,c1=nil if !ok { c1 = nil } else { fmt.Println(x) } case x, ok := <-c2: //如果c2未被关闭,则输出x,如果x关闭,c2=nil if !ok { c2 = nil } else { fmt.Println(x) } } if c1 == nil && c2 == nil { break //如果=nil那么推出 } } fmt.Println("over")}
case x, ok := <-c1: //如果c1未被关闭,则输出x,如果x关闭,c1=nil
if !ok {
c1 = nil
} else {
case x, ok := <-c2: //如果c2未被关闭,则输出x,如果x关闭,c2=nil
c2 = nil
if c1 == nil && c2 == nil {
break //如果=nil那么推出
func worker(start chan bool) { timeout := time.After(30 * time.Second) for { select { // … do some stuff case <- timeout: return } }}
func worker(start chan bool) {
timeout := time.After(30 * time.Second)
// … do some stuff
case <- timeout:
func worker(start chan bool) { heartbeat := time.Tick(30 * time.Second) for { select { // … do some stuff case <- heartbeat: //… do heartbeat stuff } }}
heartbeat := time.Tick(30 * time.Second)
case <- heartbeat:
//… do heartbeat stuff
Go之go与channel组合使用
原文:http://www.cnblogs.com/anbylau2130/p/4243735.html