ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

go语言中的只读/只写管道,多路复用select,捕获协程异常

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 00123hello world 14hello world 2hello world 3hello 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) }现在的现象是:一个协程报错了另外一个协程不会正常执行。我们要来解决这个问题
返回列表