go channel是通过通信来实现 共享内存,以及线程同步的,而不是通过共享内存来实现线程通信的.
channel创建
channel数据读写
线程同步
channel是通过读取通道里的数据,然后来实现同步的。如下例子:
package main
import (
"fmt"
)
var ch = make(chan int)
func lammySay(){
str :="hello, i am lammy! who are you ?"
for _, i := range str{
fmt.Printf("%c",i)
}
fmt.Println()
// 向channel存取数据
ch <- 666
}
func lalalaSay(){
//取到数据之前 堵塞
<-ch
str :="i am lalala , how do you do !"
for _, i := range str{
fmt.Printf("%c",i)
}
}
func main() {
go lammySay()
go lalalaSay()
for{
fmt.Print()
}
}
执行:
无缓冲区: 存入读取一次,存入后未取,再存入就会堵塞,同样未存,就取也会堵塞。
有缓冲区: 只有当缓冲区满了,才会堵塞存;只有缓冲区空时,才会堵塞取。
len(channel) 返回缓冲区现有数据长度
cap(channel) 返回缓冲区的大小
close(channel) 关闭 channel,关闭后,读取不到数据。如下,如果其他协程关掉 channel 则会跳出循环
遍历channel:
// 如果读取到数据,则 打印,没有数据 则堵塞, ok为flase则管道关闭
if num, ok := <- ch; ok==true{
fmt.Println(num)
}else {
// 如果没有读取到 管道关闭
fmt.Println("管道关闭了")
break
}
// range 遍历
for num := range ch {
fmt.Println(num)
}
下面的例子,是有缓冲区的例子:
lammysay是打电话的一方,写入要拨打的对象
answerSay 是接电话处理机制,根据lammy拨打的对象参数 who来决定谁来回复
缓冲区size为2,因此,当打第三个人的时候,则需要等待前2个拨打的取出数据才能,继续拨打
package main
import (
"fmt"
)
var ch = make(chan string , 2)
func lammyCall(who string ){
str :="hello, i am lammy! how do you do"
fmt.Println(str)
ch <- who
fmt.Println()
}
func answerSay(){
for {
//取到数据之前 堵塞
a := <-ch
if a == "lalala" {
str := "i am lalala , how do you do !"
fmt.Printf("%s", str)
fmt.Println()
}
if a == "hahaha" {
str := "i am hahaha , how do you do !"
fmt.Printf("%s", str)
fmt.Println()
}
if a == "hehehe" {
str := "i am hehehe , how do you do !"
fmt.Printf("%s", str)
fmt.Println()
}
}
}
func main() {
go lammyCall("lalala")
go lammyCall("hahaha")
go lammyCall("hehehe")
go answerSay()
for{
fmt.Print()
}
}
执行的结果不唯一,跟 写入channel的who的顺序有关系,即cpu时间轮片有关,这里贴出一次执行的结果:
单通道 channel
|
请发表评论