go语言中的只读/只写管道,多路复用select,捕获协程异常
创建一个只写管道
只写管道只能往管道里面写数据,不能从管道里面读取数据,
通过 chan<- 来创建一个只写管道
package main
func main() {
// 创建一个 int 类型的管道,只能写入数据
chWrite := make(chan<- int, 1000)
// 往管道里面写数据
chWrite <- 100
}
创建一个只读管道
只读管道只能从管道里面读取数据,不能往管道里面写数据,
通过 <-chan 来创建一个只读管道
package main
import "fmt"
func main() {
// 创建一个只读的管道
chRead := make(<-chan int, 1000)
fmt.Println(chRead)
}
区分只读管道和只写管道
<- 在前面的是,只读管道; 如:make(<-chan int, 1000)
<- 在后面的是,只写管道; 如:make(chan<- int, 1000)
定义两个方法,一个方法给管道里面写数据,一个给管道里面读取数据。要求同步进行。
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
// 变成只写管道
func writeData(ch chan<- int) {
// 往管道里面写数据,写10个数据
for i := 0; i < 10; i++ {
ch <- i * 100
fmt.Printf("写入管道中的数据是:%d,成功的\n", i*100)
time.Sleep(time.Millisecond * 50)
}
// 关闭管道
close(ch)
wg.Done()
}
// 变成只读管道
func readData(ch <-chan int) {
for v := range ch {
fmt.Printf("读取管道中的数据是:%d,成功的\n", v)
time.Sleep(time.Millisecond * 50)
}
wg.Done()
}
func main() {
var ch1 = make(chan int, 10)
wg.Add(1)
go writeData(ch1)
wg.Add(1)
go readData(ch1)
wg.Wait()
fmt.Println("程序结束")
}
select 语句
select 的使用类似于switch语句,它有一系列case分支和一个默认的分支。
每个case会对应一个管道的通信(接收或发送)过程。
select会一直等待,直到某个case的通信操作完成时,
就会执行case分支对应的语句。具体格式如下
注意点:使用select来获取channel里面的数据的时候不需要关闭channel。
关闭了反而会出现问题的哈。
package main
import (
"fmt"
)
func main() {
intChan := make(chan int, 10)
for i := 0; i < 5; i++ {
intChan <- i
}
stringChan := make(chan string, 10)
for i := 0; i < 5; i++ {
stringChan <- "hello world " + fmt.Sprintf("%d", i)
}
// // 使用select来获取channel里面的数据的时候不需要关闭channel
for {
select {
// 从intChan读取数据,随机的执行一个case
case i := <-intChan:
fmt.Println(i)
// 从stringChan读取数据,随机的执行一个case
case s := <-stringChan:
fmt.Println(s)
default:
fmt.Println("数据读取完成")
return
}
}
}
输出的如下:
hello world 0
0
1
2
3
hello world 1
4
hello world 2
hello world 3
hello world 4
数据读取完成
一个协程报错,不影响另外的协程
package main
import (
"fmt"
"time"
)
func SayHello() {
for i := 0; i < 5; i++ {
time.Sleep(time.Microsecond * 50)
fmt.Println("hello world")
}
}
// 这个代码有问题,会报错
func Test() {
var myMap map[int]string
myMap[0] = "hello world"
}
func main() {
go SayHello()
go Test()
// 防止主程序提前退出
time.Sleep(time.Second)
}
现在的现象是:一个协程报错了,另外一个协程不会正常执行。
我们要来解决这个问题
作者:流年少年
出处:https://www.cnblogs.com/ishoulgodo/
本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
如果文中有什么错误,欢迎指出。以免更多的人被误导。
出处:https://www.cnblogs.com/ishoulgodo/
想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,或者关注博主,在此感谢!
万水千山总是情,打赏5毛买辣条行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主(っ•̀ω•́)っ✎⁾⁾!
想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!
支付宝
微信
如果文中有什么错误,欢迎指出。以免更多的人被误导。

浙公网安备 33010602011771号