多go程通信(管道channel)
go 程通信
1、当涉及到多go程时,c 是使用互斥量,上锁来保持资源同步,避免资源竞争问题
2、go语言也支持这种方式,但go语言更好的解决方案是使用管道、通道channel
3、使用通道不需要我们去加锁
4、A往通道里写数据, B从通道中读数据,go自动帮我们做好了数据同步
用例:
package main
import (
"fmt"
)
func main() {
// 创建管道
// 无缓冲通道
numChan := make(chan int) // 装数字的管道, 使用管道时一定要用make,同map一样,否则是nil
// strChan := make(chan string) // 装字符串的管道
// 有缓冲通道
// numChan := make(chan int, 10)
go func() {
for i := 0; i < 50; i++ {
// 从管道中读出数据
res := <-numChan
fmt.Printf("**** 读出 i: %v ****\n", res)
}
}()
go func() {
for i := 0; i < 20; i++ {
// 向管道中写入数据
numChan <- i
fmt.Printf("==子go程===>写入i: %d\n", i)
// time.Sleep(1 * time.Second)
}
}()
for i := 20; i < 50; i++ {
// 向管道中写入数据
numChan <- i
fmt.Printf("==主go程===>写入i: %d\n", i)
// time.Sleep(1 * time.Second)
}
}
结论
1、当缓冲写满的时候,写阻塞;被读取后,再次恢复写。
2、当缓冲区读取完毕,读阻塞。
3、如果管道没有使用make分配空间,那么管道默认是nil的, 读取、写入都会阻塞。
4、对于一个管道,读与写的次数,必须对等。
通道读写对等
go通道使用时,要求我们读写一致,如果不一致会导致一下情况:
1、当读程序是在主进程进行时, 那么会导致程序崩溃
2、当读程序是在go程进行时, 那么会导致内存泄漏。(此时程序不会崩溃,但是会导致资源无法释放)
用例:
package main
import (
"fmt"
"time"
)
func main() {
// 有缓冲管道
nummChan := make(chan int, 10)
// 写
go func() {
for i := 0; i < 20; i++ {
nummChan <- i
fmt.Printf("子go程写: %v\n", i)
}
}()
// 读:go程
go func() {
for i := 0; i < 30; i++ {
aa := <-nummChan
fmt.Printf("主进程读: %v\n", aa)
}
}()
// 读:主进程
// for i:=0; i<30;i++ {
// aa := <- nummChan
// fmt.Printf("主进程读: %v\n", aa)
// }
for {
fmt.Printf("----> 主进程, 死循环\n")
time.Sleep(1 * time.Second)
}
}
- 当执行主进程读时, 程序读取超出后会立即崩溃
- 当执行go程读时, 程序读取超出后会阻塞住(结论2)
for - range 变量管道
1、遍历管道时,只返回一个值
2、for range 是不知道管道是否已经写完,所以会一直在这里等待
3、在写入端,将管道关闭,for range 关闭的管道时,会自动退出
用例:
package main
import (
"fmt"
)
func main() {
numChan := make(chan int, 10)
// 写
go func () {
for i:=0; i<20; i++ {
numChan <- i
fmt.Printf("----> 子go程写入数据\n")
}
fmt.Printf("===== 写入完毕 =====")
close(numChan)
}()
// 读
for i:= range numChan {
fmt.Printf("--> 主进程读: %v\n", i)
}
}
总结:
- 当管道写满了,写阻塞。
- 当缓冲读完了,读阻塞。
- 如果管道没有使用make分配空间,管道默认是nil 值
- 从nil 的管道中读取数据、写入数据,都是阻塞(注意:不会崩溃)
- 从一个close的管道中读取数据,会返回零值(不会崩溃)
- 关闭一个已经close的管道,程序会崩溃
- 关闭管道的操作应该放在写入端
- 读、写次数一定要对等,否则:
- 在多个go程中,资源泄露
- 在主go程中,程序崩溃(报:deadlock!)

浙公网安备 33010602011771号