golang , chan学习

news2025/1/2 23:33:16

管道是阻塞的,管道的写法,管道内容读取,和写入

package main

import "fmt"

func main() {
	// 管道声明 chan是关键字 int是类型
	// var chan1 chan int
	chan1 := make(chan int)
	fmt.Println(chan1)

	// 无缓冲通道,不会存储数据,会直接流入管道
	// 它的容量是 0,不能存储任何数据
	// 数据并不会在 channel 中做任何停留。这也意味着,无缓冲 channel 的发送和接收操作是同时进行的,它也可以称为同步 channel
	c := make(chan int)
	go func() {
		defer fmt.Println("goroutine over")
		fmt.Println("goroutine正在运行...")
		c <- 666 // 流入管道
	}()

	// 管道的读取是会被阻塞的
	// 接收:receive
	num, ok := <-c
	if ok {
		println("the chan is ok and num is ", num)
	}
	fmt.Println("main goroutine over")

}


带容量的chain,如果满了,那么发送的时候会阻塞,如果空了,那么接受的时候会阻塞

package chandemo

import (
	"fmt"
	"time"
)

func bufferChannel() {
	// 带容量的chan
	c := make(chan int, 3)

	// len是实际的,cap是客观的容量
	fmt.Println("len(c) = , cap(c) = ", len(c), cap(c))

	go func() {
		defer fmt.Println("子go结束")

		// 轮询向管道发送数据
		// 如果队列已满,则阻塞等待,直到另一个 goroutine 执行,接收操作释放队列的空间
		for i := 0; i < 3; i++ {
			c <- i
			fmt.Println("子go程正在运行,发送的元素=i", i, " len(C) = ", len(c), "cap(c)", cap(c))
		}
	}()

	// 保证先发送完成
	time.Sleep(2 * time.Second)

	// 循环接收数据
	// 接收操作是从队列的头部获取元素并把它从队列中删除,如果队列为空,则阻塞等待,直到另一个 goroutine 执行,发送操作插入新的元素
	for i := 0; i < 3; i++ {
		num := <-c
		fmt.Println("num of i is ", num)
	}

	fmt.Println("main 结束")
}

单向管道,

  • 只能由发送方关闭管道:
    由发送方负责关闭管道,接收方不能关闭管道。
    如果接收方尝试关闭管道,会引发运行时错误。

  • 重复关闭会导致 panic:
    如果对同一个管道调用多次 close,会导致 panic。
    因此,关闭操作应确保在逻辑上只调用一次。

  • 关闭后的管道可以继续接收数据
    但不能再向关闭的管道发送数据,否则会引发 panic。

package chandemo

import "fmt"

// onlySend
func counter(out chan<- int) {
	for i := 0; i < 100; i++ {
		out <- i
	}
	// 发送完成后,关闭管道
	// 关闭管道可以向接收方表明,管道中不会再有新的数据。
	close(out)
}

// out是只能发送,in是只能接受
func squarer(out chan<- int, in <-chan int) {
	for i := range in {
		out <- i * i
	}
	close(out)
}

// 只能接收数据的管道
// in 为单向接收管道,用于从上游接收数据并打印
func printer(in <-chan int) {
	// 当管道关闭且数据读取完毕时,会自动退出循环
	for val := range in {
		fmt.Printf("收到数据: %d\n", val)
	}
}

func testSingleChan() {
	ch1 := make(chan int)
	ch2 := make(chan int)
	// ch1 -> ch2 -> printer
	// 启动counter,将数据发送给ch1
	go counter(ch1)
	// 启动squarer,将ch1的数据平方后发送给ch2
	go squarer(ch2, ch1)
	// 启动printer,从ch2接收数据并打印
	printer(ch2)
}

// 管道避免死锁
func main() {
    ch := make(chan int)

    go func() {
        ch <- 42 // 发送数据
        close(ch) // 关闭管道
    }()

    val, ok := <-ch
    fmt.Println(val, ok) // 42 true
    
	// 检查管道是否关闭
    val, ok = <-ch
    fmt.Println(val, ok) // 0 false (管道已关闭,没有数据)
}

select + chan实现多路复用

func main() {

   //声明三个存放结果的channel
   firstCh := make(chan string)
   secondCh := make(chan string)
   threeCh := make(chan string)

   //同时开启3个goroutine下载
   go func() {
      firstCh <- downloadFile("firstCh")
   }()

   go func() {
      secondCh <- downloadFile("secondCh")
   }()

   go func() {
      threeCh <- downloadFile("threeCh")
   }()

   //开始select多路复用,哪个channel能获取到值,
   //就说明哪个最先下载好,就用哪个。
   select {
      case filePath := <-firstCh:
         fmt.Println(filePath)
      case filePath := <-secondCh:
         fmt.Println(filePath)
      case filePath := <-threeCh:
         fmt.Println(filePath)
   }
}

func downloadFile(chanName string) string {

   //模拟下载文件,可以自己随机time.Sleep点时间试试
   time.Sleep(time.Second)
   return chanName+":filePath"
}

// channel来退出
func testselectclose() {
	ch := make(chan int)

	go func() {
		for i := 1; i <= 3; i++ {
			ch <- i
		}
		close(ch)
		// ch <- 1// panic: send on closed channel
	}()

	for {
		select {
		case val, ok := <-ch:
			// 检测到false,因为close了,那么就会推出
			if !ok {
				fmt.Println("Channel closed, exiting.")
				return
			}
			fmt.Println("Received:", val)
		}
	}
}

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

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

相关文章

模型工作流:自动化的模型内部三角面剔除

1. 关于自动减面 1.1 自动减面的重要性及现状 三维模型是游戏、三维家居设计、数字孪生、VR/AR等几乎所有三维软件的核心资产&#xff0c;模型的质量和性能从根本上决定了三维软件的画面效果和渲染性能。其中&#xff0c;模型减面工作是同时关乎质量和性能这两个要素的重要工…

黑马程序员Java笔记整理(day08)

1.代码块 静态代码块 实例代码块 2.内部类 成员内部类 静态内部类 局部内部类 匿名内部类 认识 常见使用形式 应用场景 简化版本 另一个应用场景 3.函数式编程 Lambda 函数简化 方法引用 4.常用API String ArrayList 5.GUI编程 快速认识 事件处理 三种常用写法 第一种 第二…

redis延迟队列

Redis延迟队列 Redis延迟队列是基于Redis构建的消息队列&#xff0c;用来处理需延迟执行的任务。 基本原理 它借助Redis的有序集合&#xff08;Sorted Set&#xff09;数据结构达成目的。会把任务及其执行时间分别当成成员与分值存进有序集合&#xff0c;由于执行时间作为分值&…

爱思唯尔word模板

爱思唯尔word模板 有时候并不一定非得latex https://download.csdn.net/download/qq_38998213/90199214 参考文献书签链接

【JDBC】入门增删改查

JDBC JDBC概述 JDBC&#xff08;Java DataBase Connectivity, java数据库连接&#xff09;是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范&#xff0c;可以为不同的关系型数据库提供统一访问&#xff0c;它由一组用Java语言编写的接口和类组成。 XML方式…

Java开发-后端请求成功,前端显示失败

文章目录 报错解决方案1. 后端未配置跨域支持2. 后端响应的 Content-Type 或 CORS 配置问题3. 前端 request 配置问题4. 浏览器缓存或代理问题5. 后端端口未被正确映射 报错 如下图&#xff0c;后端显示请求成功&#xff0c;前端显示失败 解决方案 1. 后端未配置跨域支持 …

Dify服务器部署教程

Dify的github地址: https://github.com/langgenius/dify 服务器要求&#xff1a;2c4g 1、克隆仓库 可以通过命令或者下载zip解压后上传服务器都行 git clone https://github.com/langgenius/dify.git 2、docker启动 cd dify/dockercp .env.example .envdocker compose up -d…

砝码称重(2021年蓝桥杯)

【问题描述】 你有一架天平和N个砝码&#xff0c;这N个砝码的重量依次是w1,w2,……,wn。&#xff08;1~n为下标&#xff09; 请你计算利用N个砝码一共可以称出多少种不同的重量&#xff1f; 【注意】砝码可以放在天平的两边 【输入格式】 第一行包含一个整数N。 第二行包含N个…

KaiOS 4.0 | DataCall and setupData implemention

相关文档 1、KaiOS 3.1 系统介绍 KaiOS 系统框架和应用结构(APP界面逻辑)文章浏览阅读842次,点赞17次,收藏5次。对于Java开发者而言,理解JS的逻辑调用是有点困难的。而KaiOS webapp开发又不同于现代的web开发,更像chrome浏览器内嵌模式。在这里梳理一下kaios平台web应用…

ArcGIS Pro地形图四至角图经纬度标注与格网标注

今天来看看ArcGIS Pro 如何在地形图上设置四至角点的经纬度。方里网标注。如下图的地形图左下角经纬度标注。 如下图方里网的标注 如下为本期要介绍的例图&#xff0c;如下&#xff1a; 图片可点击放大 接下来我们来介绍一下 推荐学习&#xff1a;GIS入门模型构建器Arcpy批量…

win系统B站播放8k视频启用HEVC编码

下载HEVC插件 点击 HEVC Video Extension 2.2.20.0 latest downloads&#xff0c;根据教程下载安装 安装 Random User-Agent 点击 Random User-Agent 安装 配置 Random User-Agent 在youtube中会导致视频无法播放&#xff0c;我选择直接屏蔽了 B站设置

mysql锁机制以及隔离级别下保证并发安全的方式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 mysql锁机制以及隔离级别下保证并发安全的方式 多事务并发执行可能出现的问题mysql有那些锁全局锁表级锁行锁 在不同的隔离级别下mysql保证并发安全的方式RU隔离级别RC隔离级…

qwenvl 以及qwenvl 2 模型架构理解

qwenvl 模型理解&#xff1a; 参考资料&#xff1a; https://qwenlm.github.io/zh/blog/qwen2-vl/ https://github.com/QwenLM/Qwen2-VL?tabreadme-ov-file https://qwenlm.github.io/zh/blog/qwen2-vl/ 论文&#xff1a; qwenvl https://arxiv.org/abs/2308.12966 Qwen2-VL …

高效使用AI完成编程项目任务的指南:从需求分析到功能实现

随着人工智能工具的普及&#xff0c;即便是零编程基础或基础薄弱的用户&#xff0c;也可以借助AI完成许多技术任务。然而&#xff0c;要高效地使用AI完成编程任务&#xff0c;关键在于如何清晰表达需求&#xff0c;并逐步引导AI实现目标。 在本文中&#xff0c;我们将通过开发…

AI生成视频字幕--VideoCaptioner/卡卡字幕助手

github: https://github.com/WEIFENG2333/VideoCaptioner 123云盘&#xff1a;https://www.123865.com/s/inrnjv-1sk6H提取码:4455 B站教程&#xff1a;https://www.bilibili.com/video/BV1giBqYtEqG?vd_source8e73ffa42accf9446f3cb7fddc85b38c 优点&#xff1a;1.免费&am…

嵌入式单片机窗口看门狗控制与实现

窗口看门狗 注意:WWDG外设没有独立的时钟源,而是挂载在APB1总线下,APB1总线外设时钟为42MHZ。 了解WWDG外设的使用流程,可以参考stm32f4xx_wwdg.c的开头注释,具体流程如下图所示

从 ELK Stack 到简单 — Elastic Cloud Serverless 上的 Elastic 可观察性

作者&#xff1a;来自 Elastic Bahubali Shetti, Chris DiStasio 宣布 Elastic Cloud Serverless 上的 Elastic Observability 正式发布 — 一款完全托管的可观察性解决方案。 随着组织规模的扩大&#xff0c;一个能够处理分布式云环境的复杂性并提供实时洞察的可观察性解决方…

【教程】通过Docker运行AnythingLLM

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 官方教程&#xff1a;Local Docker Installation ~ AnythingLLM 1、先创建一个目录用于保存anythingllm的持久化文件&#xff1a; sudo mkdir /app su…

RabbitMQ基础篇之快速入门

文章目录 一、目标需求二、RabbitMQ 控制台操作步骤1.创建队列2.交换机概述3.向交换机发送消息4.结果分析5.消息丢失原因 三、绑定交换机与队列四、测试消息发送五、消息查看六、结论 一、目标需求 新建队列&#xff1a;创建 hello.queue1 和 hello.queue2 两个队列。消息发送…

Lottie动画源码解析

Lottie是一个很成熟的开源动画框架&#xff0c;它支持直接使用从AE导出的动画文件&#xff0c;在不同平台均可快速使用&#xff0c;大大减轻了程序员的工作量&#xff0c;也让复杂的动画成为可能。该动画文件使用Json格式来描述内容&#xff0c;可以大大缩减文件的体积。在Andr…