使用Channel的一些业务场景

news2024/11/24 19:53:54

在这里插入图片描述

使用Channel的一些业务场景

首先需要明确的就是,发送方才知道什么时候关闭 channel ,这个是比较符合逻辑的。
我们需要知道哪些情况会使 channel 发生 panic

  • 关闭一个 nil 值会引发
  • 关闭一个已经关闭的 channel 会引发
  • 向一个已经关闭的 channel 发送数据会引发

常见应用场景

  • 信号通知
  • 超时控制
  • 生产消费模型
  • 数据传递
  • 控制并发数
  • 互斥锁
  • one million……

信号通知

如果只是单纯的使用通知操作,那么类型就使用 struct{} 。因为空结构体在 go 中是不占用内存空间的

package main

import (
  "fmt"
  "time"
)

func main() {
  isOver := make(chan struct{})
  go func() {
    collectMsg(isOver)
  }()
  <-isOver
  calculateMsg()
}

// 采集
func collectMsg(isOver chan struct{}) {
  time.Sleep(500 * time.Millisecond)
  fmt.Println("完成采集工具")
  isOver <- struct{}{}
}

// 计算
func calculateMsg() {
  fmt.Println("开始进行数据分析")
}

超时控制

<-time.After(1 * time.Second) 是过了指定时间后返回一个 channelselect case 是哪一个 channel 先有反应就先处理,所以可以做到一个超时控制的作用

func main() {
  select {
  case <-doWork():
    fmt.Println("任务结束")
  case <-time.After(1 * time.Second):
    fmt.Println("任务处理超时")
  }
}

func doWork() <-chan struct{} {
  ch := make(chan struct{})
  go func() {
    // 任务处理耗时
    time.Sleep(2 * time.Second)
    close(ch)
  }()
  return ch
}

消费者模型

这个就不多说了,一个生产,一个消费

数据传递

type token struct{}

func main() {
  num := 4
  var chs []chan token
  // 4 个work
  for i := 0; i < num; i++ {
    chs = append(chs, make(chan token))
  }
  for j := 0; j < num; j++ {
    go worker(j, chs[j], chs[(j+1)%num])
  }
  // 先把令牌交给第一个
  chs[0] <- struct{}{}
  select {}
}

func worker(id int, ch chan token, next chan token) {
  for {
    // 对应work 取得令牌
    token := <-ch
    fmt.Println(id + 1)
    time.Sleep(1 * time.Second)
    // 传递给下一个
    next <- token
  }
}

控制并发数

func main() {
  limit := make(chan struct{}, 10)
  jobCount := 100
  for i := 0; i < jobCount; i++ {
    go func(index int) {
      limit <- struct{}{}
      job(index)
      <-limit
    }(i)
  }
  time.Sleep(20 * time.Second)
}

func job(index int) {
  // 耗时任务
  time.Sleep(1 * time.Second)
  fmt.Printf("任务:%d已完成n", index)
}

互斥锁

我们也可以通过 channel 实现一个小小的互斥锁。通过设置一个缓冲区为1的通道,如果成功地往通道发送数据,说明拿到锁,否则锁被别人拿了,等待他人解锁。

type ticket struct{}

type Mutex struct {
  ch chan ticket
}

// 创建一个缓冲区为1的通道作
func newMutex() *Mutex {
  return &Mutex{ch: make(chan ticket, 1)}
}

// 谁能往缓冲区为1的通道放入数据,谁就获取了锁
func (m *Mutex) Lock() {
  m.ch <- struct{}{}
}

// 解锁就把数据取出
func (m *Mutex) unLock() {
  select {
  case <-m.ch:
  default:
    panic("已经解锁了")
  }
}

func main() {
  mutex := newMutex()
  go func() {
    // 如果是1先拿到锁,那么2就要等1秒才能拿到锁
    mutex.Lock()
    fmt.Println("任务1拿到锁了")
    time.Sleep(1 * time.Second)
    mutex.unLock()
  }()
  go func() {
    mutex.Lock()
    // 如果是2拿先到锁,那么1就要等2秒才能拿到锁
    fmt.Println("任务2拿到锁了")
    time.Sleep(2 * time.Second)
    mutex.unLock()
  }()
  time.Sleep(500 * time.Millisecond)
  // 用了一点小手段这里最后才能拿到锁
  mutex.Lock()
  mutex.unLock()
  close(mutex.ch)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/666457.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

职场人的AI私塾,帮你打造得力的AI助手

你有没有想过&#xff0c;为什么有一些周围的小伙伴&#xff0c;工作量看着也不少&#xff0c;但事务处理速度特别快&#xff0c;质量也不差&#xff1b;一些看起来难度比较大或者生疏的工作&#xff0c;也能轻松应付得来&#xff0c;难道他们都是天生的工作能力出众&#xff1…

小白速看!带你轻松解决Java的空指针异常

关注“Java架构栈”微信公众号&#xff0c;回复暗号【Java面试题】即可获取大厂面试题 异常案例 对很多Java初学者来说&#xff0c;在学习的初期是很容易遇到各种异常的&#xff0c;就比如咱们今天要讲的这个空指针异常。所谓“授之以鱼&#xff0c;不如授之以渔”&#xff0c;…

Q-Vision+Kvaser CAN/CAN FD/LIN总线解决方案

智能联网技术在国内的发展势头迅猛&#xff0c;随着汽车智能化、网联化发展大潮的到来&#xff0c;智能网联汽车逐步成为汽车发展的主要趋势。越来越多整车厂诉求&#xff0c;希望可以提供本土的测量软件&#xff0c;特别是关于ADAS测试。对此&#xff0c;Softing中国推出的Q-V…

CppUnit——【由JUnit移植过来的】C++单元测试框架——的下载安装

C单元测试框架CppUnit的下载与安装 简介下载地址导入到Virtual Studio准备条件根据VS版本选择导入对应的.sln文件 简介 CppUnit是【由JUnit移植过来的】C测试框架。 下载地址 从我使用的CppUtest框架中的文档/readme/ReadmePart1_VisualStudio.rtf文件中看到了官网的地址cpp…

前端性能优化:高在性能,大在范围,必要前置知识一网打尽!(下)

前言 在上一篇 前端性能优化&#xff1a;高在性能&#xff0c;大在范围&#xff0c;必要前置知识一网打尽&#xff01;&#xff08;上&#xff09; 一文中介绍了和前端性能优化相关的一些前置知识&#xff0c;那么本篇就针对优化方案进行总结&#xff0c;核心的方向还是上篇文…

C++基础(6)——类和对象(4)

前言 本文主要介绍了C中运算符重载的基本知识。 4.5.1&#xff1a;加号运算符重载&#xff08;成员函数和全局函数都可实现&#xff09; 运算符重载&#xff1a;对已有的运算符重新进行定义&#xff0c;赋予其另一种功能&#xff0c;以适应不同的数据类型 1&#xff1a;成员…

管理类联考——写作——素材篇——论说文——写作素材03——志篇:逆境·考验04——志篇:初心

管理类专业学位联考 (写作能力) 论说文素材 03——志篇&#xff1a;逆境考验 论文说材料: 逆境是天才的进身之阶&#xff1b;信徒的洗礼之水&#xff1b;能人的无价之宝&#xff1b; 弱者的无底之渊。 ——巴尔扎克 一&#xff1a;道理论据 不是一番寒彻骨&#xff0c;怎得…

【Azure】微软 Azure 基础解析(九)Azure 标识、身份管理、Azure AD 的功能与用途

本系列博文还在更新中&#xff0c;收录在专栏&#xff1a;「Azure探秘&#xff1a;构建云计算世界」 专栏中。 本系列文章列表如下&#xff1a; 【Azure】微软 Azure 基础解析&#xff08;三&#xff09;云计算运营中的 CapEx 与 OpEx&#xff0c;如何区分 CapEx 与 OpEx 【A…

测量设备频宽范围选择要素—系统响应速度

系统响应速度是输入信号经过电压/电流驱动系统输出响应的幅值升到终值过程的斜率&#xff0c;而上升时间是系统响应速度的一种度量&#xff0c;上升时间越短&#xff0c;响应速度越快。 由一阶系统响应定义中&#xff0c;稳定的一阶系统上升时间 定义是响应从终值10%上升到终值…

git常用命令合集(建议收藏)

1、git init将本文件夹初始化成一个本地git仓库 2、git clone&#xff07;xxx&#xff07;将github上的远程克隆到本地 3、git add [file1] [file2] 添加文件到暂存区&#xff0c;包括修改的文件、新增的文件 4、git add [dir] 添加目录到暂存区&#xff0c;包括子目录 5、…

java 类之间相互引用实例探索

本文记录一下自己对类之间相互引用的探索&#xff0c;如有错误&#xff0c;希望不吝赐教 问题一&#xff1a;类之间相互引用依赖会不会引用死循环 不会&#xff0c;例如&#xff1a;A类中声明一个B类的引用&#xff0c;B类中也声明一个A类的引用&#xff0c;因为类之间的引用相…

TCP为什么要三次握手与四次分手?

概要 TCP协议是五层协议中运输层的协议&#xff0c;下面依赖网络层、链路层、物理层&#xff0c;对于一个报文想发到另一台机器(假设是服务器)上对等层&#xff0c;每一个所依赖的层都会对报文进行包装&#xff0c;例如TCP协议就依赖网络层的IP协议&#xff0c;所以发送的报文会…

【数据库数据恢复】SQL Server数据表结构损坏的数据恢复案例

数据库故障&分析&#xff1a; SQL server数据库数据无法读取。 经过初检&#xff0c;发现SQL server数据库文件无法被读取的原因是因为底层File Record被截断为0&#xff0c;无法找到文件开头&#xff0c;数据表结构损坏。镜像文件的前面几十M空间和中间一部分空间被覆盖掉…

大专毕业,干了 3 年外包,废了····

如果不是女朋友和我提分手&#xff0c;我估计到现在还是外包公司呆着 大专生&#xff0c;19年通过校招进入湖南某软件公司&#xff0c;干了接近3年的点点点&#xff08;功能测试&#xff09;&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在…

VSCode借助Remote-SSH扩展,远程调试linux系统的机器人

本文主要介绍使用VSCode借助Remote-SSH扩展&#xff0c;远程调试linux系统的机器人的方法 在我之前的文章&#xff1a; ROS主机搭建NFS服务器&#xff0c;虚拟机通过挂载访问及修改主机文件 中介绍了采用挂载到的方式进行远程调试的方法&#xff0c;本文将介绍另一种方法&#…

汽车三高试验离不开的远程试验管理平台——TFM

一 背景 众所周知&#xff0c;车辆在量产之前都要经过长时间的耐久性试验和多种汽车适应性或法规试验。道路试验就是在汽车上装设测试仪表和施加模拟载荷&#xff0c;并按实际使用条件来进行测试。此外&#xff0c;在实际试验场地和试验时间上也是有一定规定的。企业根据不同的…

导出符号表和字符设备驱动

目录 1. 导出符号表 1.1. 应用场景&#xff1a;驱动B想要使用驱动A的函数 1.2. 函数解析 1.3. 撰写提供者.c文件 1.4. 撰写提供者makefile文件 1.5. 执行makefile文件生成Module.symvers 1.6. 撰写调用者.c文件 1.7. 撰写调用者的makefile 1.8. 调用验证 2. 字符设备…

springCloud对接kafka+websockt消息中心

1.网关没有配置message和websockt的路由 2.message启动报错&#xff0c;线上zookeeper启动失败导致 3.message配置文件参数读取不到&#xff0c;原因&#xff1a;message_dev.yml 正确名称 message-dev.yml 4.线上websockt地址连接失败&#xff0c;原因&#xff1a;白名单没…

Cisco MPLS VPN Option C2

无RR 一、拓扑 环境:AR1-AR8各有loopback0接口分别是1.1.1.1 2.2.2.2 二、配置步骤 1、配置AS100和AS200的底层网络&#xff0c;这里使用OSPF配置 2、配置AS内使用LDP协议分发标签 3、ASBR之间建立EBGP邻居关系&#xff0c;相对端通告路由时携带标签&#xff0c;互联…

确保消息不会丢失

现在主流的消息队列产品都提供了非常完善的消息可靠性保证机制&#xff0c;完全可以做到在消息传递过程中&#xff0c;即使发生网络中断或者硬件故障&#xff0c;也能确保消息的可靠传递&#xff0c;不丢消息。 绝大部分丢消息的原因都是由于开发者不熟悉消息队列&#xff0c;没…