当前位置: 首页 > article >正文

Go语言 管道2

本篇文章主要介绍Go语言 管道:判断管道关闭、单向通道及多管道协同工作内容和示例。

目录

如何判断管道关闭

单向通道

Select

总结


如何判断管道关闭

需要知道一个管道的状态,如果已经关闭了,读不会有问题,会返回零;

但是如果继续写,会有崩溃风险。

可以使用map时,使用的ok-idom模式判断,如下:

map ==> v, ok := m1[0]

channel ==> v, ok := <-numChan

示例如下:

package main

import "fmt"

func main() {
   numChan := make(chan int, 10)

   // 写
   go func() {
      for i:= 0; i< 10;i++{
         numChan <- i
         fmt.Println("写入数据:", i)
      }
      close(numChan)
   }()

   for {
      v, ok := <- numChan // ok-idom模式判断
      if !ok {
         fmt.Println("管道已关闭,准备退出")
         break
      }
      fmt.Println("v:", v)
   }

   fmt.Println("结束")
}

 

单向通道

NumChan := make(chan int, 10) ==> 双向通道,既可以读,也可以写

单向通道:为了明确语义,一般用于函数参数

        单向读通道:var numChanRead <- chan int

        单向写通道:var numChanWrite chan <- int

示例如下:

package main

import (
   "fmt"
   "time"
)

func main() {
   // 单向读通道:
   // var numChanRead <- chan int
   // 单向写通道:
   // var numChanWrite chan <- int

   // 生产者消费者模型
   // c:数组+锁 thread1:写 thread2:读
   // Go: goroutine + channel

   // 1.在主函数中创建一个双向通道 numChan
   numChan := make(chan int, 10)

   // 2.将numChan 传递给producer,负责生产
   // 双向通道可以赋值给同类型的单向通道,单向不能转双向
   go producer(numChan)

   // 3.将numChan 传递给consumer 负责消费
   go consumer(numChan)

   time.Sleep(2 * time.Second)
   fmt.Println("结束")
}

// producer 生产者 ==》 提供一个只写的通道
func producer(out chan<- int) {
   for i := 0; i < 10; i++ {
      out <- i
      // data := <- out // 写通道不允许有读取操作
      fmt.Println("======> 向管道中写入数据:", i)
   }
}

// consumer 消费者 ==》 提供一个只读的通道
func consumer(in <- chan int)  {
   // in <- 1 // 读通道不允许有写入操作
   for v := range in {
      fmt.Println("从管道中读取数据:", v)
   }
}

 

Select

当程序中有多个channel协同工作:ch1,ch2;

某一个时刻,ch1或者ch2触发了,程序要做相应的处理,

使用select来监听多个通道,当管道被触发时(写入数据,读取数据,关闭管道)。

select语法与switch case很像,但是所有的分支条件都必须是通道io

示例如下:

package main

import (
   "fmt"
   "time"
)

func main() {
   // var ch1,ch2 chan int
   ch1 := make(chan int)
   ch2 := make(chan int)

   // 启动一个go程,负责监听两个channel
   go func() {
      for {
         fmt.Println("监听中。。。。。。。。。。。。。。。。")
         select {
         case data1 := <-ch1:
            fmt.Println("从ch1读取数据成功,data1:", data1)
         case data2 := <-ch2:
            fmt.Println("===> 从ch2读取数据成功,data2:", data2)
         default:
            fmt.Println("select default 分支 called")
            time.Sleep(time.Second)
         }
      }
   }()

   // 启动go程1 写ch1
   go func() {
      for i := 0; i < 10; i++ {
         ch1 <- i
         time.Sleep(1 * time.Second / 2)
      }
   }()

   // 启动go程2 写ch2
   go func() {
      for i := 0; i < 10; i++ {
         ch2 <- i
         time.Sleep(1 * time.Second)
      }
   }()

   for {
      fmt.Println("结束")
      time.Sleep(5 * time.Second)
   }
}

总结

本篇文章主要介绍Go语言 管道:判断管道关闭、单向通道及多管道协同工作内容和示例。


http://www.kler.cn/a/300376.html

相关文章:

  • 2024年度总结:从后端Java到全栈成长的蜕变
  • HTML<center>标签
  • nginx 配置代理,根据 不同的请求头进行转发至不同的代理
  • 【专题二 二叉树中的深搜】98. 验证二叉搜索树
  • llava 导入process报错
  • 搜维尔科技:Xsens人形机器人解决方案的优势
  • leetcode hot100_part4_子串
  • Pycharm中的Director和Python Package
  • C语言练习题3
  • 如何用 Helm Chart 安装指定版本的 GitLab Runner?
  • 微软 Power Apps MDA 模型驱动应用解决Image字段查询出来缩略图问题变原图方法(c#+Plugin方式)
  • springboot 整合quartz定时任务
  • /bin/bash的作用
  • idea2023版使用Free MyBatis plugin插件报错
  • 说说相机标定?
  • illusionX——一个从理解情感到改变学习、创新教育体验集成情感计算的混合现实系统
  • 测试阶段例题
  • uniapp+uview-plus实现微信小程序自定义tabbar
  • 1.C++入门1(c++编译过程,命名空间,C++输入输出,缺省参数)
  • 代码随想录训练营 Day57打卡 图论part07 53. 寻宝(prim,kruskal算法)
  • 全国历年高考真题2008-2024
  • 互联网摸鱼日报(2024-09-09)
  • 计算机三级网络技术总结 第十一章网络管理技术
  • 在mac中使用numbers对数据进行分列(更详细的回答,已解决)
  • 基于IOT的供电房监控系统(实物)
  • gdb 前端:kdbg 安装使用