不要以共享内存的方式去通信,而是以通信的方式共享内存
- sync
- 鼓励使用channel
channel的声明
var 通道名 chan 数据类型
通道名 = make(chan 数据类型)
package main
import "fmt"
func main() {
var a chan int
fmt.Printf("%T,%v\n",a,a)
}

channel
data := <-a //read from channel a
a <- data // write to channel a
阻塞
发送数据:chan<-data,阻塞的,直到另一条goroutine,读取数据来解除阻塞
读取数据:data<-chan,也是阻塞的。直到另一条goroutine,写出数据解除阻塞。
channel本身就是同步的,意味着在同一时间只能有一个goroutine使用同一个channel
如果只有读channel会报错deadlock死锁
package main
import (
"fmt"
)
func main() {
var ch1 chan bool
ch1=make(chan bool)
go func(){
for i:=0;i<10;i++{
fmt.Println("goroutine..",i)
}
ch1<-true
fmt.Println("goroutine...over...")
}()
// 没有写入ch1的时候,读ch1的操作是阻塞的
data:= <-ch1
fmt.Println("main...data:",data)
fmt.Println("main...over...")
}
close
close(ch)关闭channel后,可以用v,ok := <-ch
的ok是否为false来判断是否已经读取完毕了,前提是,写的一方一定要close掉channel
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go sendData(ch)
for {
time.Sleep(1 * time.Second)
v, ok := <-ch
if !ok {
fmt.Println("已经读取完毕...", ok)
break
}
fmt.Println("读入...", v, ok)
}
}
func sendData(ch chan int) {
for i := 0; i < 10; i++ {
fmt.Println("写入...", i)
ch <- i
}
close(ch)
}
结果有个很有趣的现象:应该是读入完才能写入,应该阻塞在写入的,为什么会出现两次写入?

因为fmt.Println("写入...", 1)
后,ch<-1
执行
到了下一个for,执行了fmt.Println("写入...", 2)
,阻塞是阻塞在ch<-2
所以打印出来了不代表真就写进channel了
for range的写法
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
go sendData(ch)
for v:=range(ch){
fmt.Println("读入",v)
}
fmt.Println("main...over...")
}
func sendData(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
}
网友评论