go的channel要在协程中读写,否则会死锁,main函数自身也是协程,一旦写入就会阻塞等待读取。例如:
lock包下代码
package lock
import (
"fmt"
"time"
)
func DeadLockwrong() {
ch := make(chan int)
ch<-1
readChan(ch)
}
func DeadLock() {
ch := make(chan int)
go writeChan(ch)
go readChan(ch)
time.Sleep(time.Second * 1)
}
func writeChan(ch chan int) {
fmt.Println("write")
ch <- 1
}
func readChan(ch chan int) {
for {
fmt.Printf("go %d", <-ch)
}
}
main函数里调用DeadLockwrong,会报错,fatal error: all goroutines are asleep - deadlock!
调用DeadLock,正常执行。
另外协程运行完后如果没有调用time.sleep,程序直接结束,go协程可能还没执行完,则不会输出打印
其他:
不能将无缓存通道理解为缓冲通道为1的通道!
无缓冲通道读写都必须在协程里,否则会阻塞。有缓冲通道则可以不需要都准备好,读或者写可以写在当前线程里而不会阻塞。