func main() { intChan := make(chan int, 10) for i := 0; i < 10; i++ { intChan <- i } for { //十次后 fatal error: all goroutines are asleep - deadlock! i := <- intChan fmt.Println(i) time.Sleep(time.Second) } }
chan关闭的情况取超出值为类型默认值,如int为0
func main() { intChan := make(chan int, 10) for i := 0; i < 10; i++ { intChan <- i } close(intChan) for { i := <- intChan //十次后i值都为0,不报错 time.Sleep(time.Second) fmt.Println(i) } }
判断chan是否取完
func main() { intChan := make(chan int, 10) for i := 0; i < 10; i++ { intChan <- i } close(intChan) for { i, ok := <- intChan if !ok { fmt.Println() return } fmt.Println(i) } }
channel 栗子 栗子一
func sendData(ch chan<- string) { ch <- ch <- ch <- ch <- ch <- close(ch) } func getData(ch <-chan string, chColse chan bool) { for { str, ok := <-ch if !ok { fmt.Println() break } fmt.Println(str) } chColse <- true } func main() { ch := make(chan string, 10) chColse := make(chan bool, 1) go sendData(ch) go getData(ch, chColse) <-chColse close(chColse) }
栗子二:interface类型chan,取出后转化为对应类型。
type user struct { Name string } func main() { userChan := make(chan interface{}, 1) u := user{Name: } userChan <- &u close(userChan) var u1 interface{} u1 = <-userChan var u2 *user u2, ok := u1.(*user) if !ok { fmt.Println() return } fmt.Println(u2) }
channel 超时处理
利用select来处理chan超时。
for { select { case v := <-chan1: fmt.Println(v) case v := <-chan2: fmt.Println(v) default: time.Sleep(time.Second) fmt.Println() } }
time.After()定时器来做处理。
在time.After()计时器触发之前,底层计时器不会被垃圾收集器回收。
select { case m := <-c: handle(m) case <-time.After(5 * time.Minute): fmt.Println() }
t := time.NewTicker(time.Second) fmt.Println(t) for v := range t.C { fmt.Println(v) } t.Stop()
定时器栗子Goroutine+Channel 栗子 栗子一
多个goroutine处理任务;
等待一组channel的返回结果。
func calc(taskChan, resChan chan int, exitChan chan bool) { defer func() { err := recover() if err != nil { fmt.Println() return } }() for v := range taskChan { // 任务处理逻辑 flag := true for i := 2; i < v; i++ { if v%i == 0 { flag = false break } } if flag { //结果进chan resChan <- v } } //处理完进退出chan exitChan <- true } func main() { //任务chan intChan := make(chan int, 1000) //结果chan resChan := make(chan int, 1000) //退出chan exitChan := make(chan bool, 8) go func() { for i := 0; i < 1000; i++ { intChan <- i } close(intChan) }() i := 0; i < 8; i++ { go calc(intChan, resChan, exitChan) } go func() { i := 0; i < 8; i++ { <-exitChan } close(resChan) close(exitChan) }() for v := range resChan { fmt.Println(v) } }
栗子二
等待一组channel的返回结果 sync.WaitGroup 的解决方法。
WaitGroup用于等待一组线程的结束。父线程调用Add方法来设定应等待的线程的数量。每个被等待的线程在结束时应调用Done方法。同时,主线程里可以调用Wait方法阻塞至所有线程结束。