Golang 关闭的Channel读写问题

golang深刻剖析——channel 对于无缓冲的 channel,一旦有 goroutine 往 channel 写入数据,那么当前的 goroutine 会被阻塞住,直到有其他的 goroutine 消费了 channel 里的数据,才能继续运行写入数据。当 G2 要读取数据时,会优先从缓冲数据区域去读取,并且在读取完后,会检查 sendq 队列,如果 goroutine 有等待队列,则会将它上面的 data 补充到缓冲数据区域,并且也对其设置 goready 函数。下面我们来捋一下这些不同之处。如果已满,则和之前的流程是一样的。 阅读详情

1.向一个已关闭的channel发送元素会引起panic

panic: send on closed channel

package main

import (
	"sync"
	"time"
)

func main() {
	ch := make(chan struct{})
	close(ch)

	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		ch <- struct{}{}
		time.Sleep(time.Second*2)
		wg.Done()
	}()
	
	wg.Wait()
	
}

 

 

2. 在发送端关闭Channel,接收端还会继续接收到通道中的元素


package main

import (
	"sync"
	"fmt"
)

func main() {
	ch := make(chan int,10)
	for i := 0 ; i < 10 ; i++ {
		ch <- i
	}
	close(ch)

	var wg sync.WaitGroup
	wg.Add(1)

	go func() {
		defer wg.Done()
		for v := range ch {
			fmt.Println(v)
		}
	}()

	wg.Wait()
	fmt.Println("over")
}

 

3. select...case... 尝试从close的channel接受数据会直接获取该channel类型的空值

package main

import (
	"fmt"
)

func main() {
	ch := make(chan struct{})
	close(ch)

	select {
	case v, ok := <-ch:
		fmt.Println("ch")
		fmt.Println(v)
		fmt.Println(ok)
	default:
		fmt.Println("default")
	}
}

该示例会走 <-ch case

openEuler 20.03 LTS面向RK3399移植系列(3)—openEuler 20.03 LTS面向Firefly RK3399的第一个版本(Linux kernel 4.4) 任务动机:完成openEuler面向RK3399开发板的移植。 任务描述:按照固件烧写准备,固件获取,固件打包和烧写的步骤实现openEuler面向RK3399开发板的移植,整理过程和相关命令记录到文档。 1. 制作openEuler的rootfs.img 1.1 开发环境 树莓派--openEuler系统 openEuler 20.03 LTS 的内测版本镜像,下载。 1.2 具体操作 1.2.1 ssh远程连接树莓派 确定树莓派IP ssh连接 1.2.2 制作rootfs.img 阅读详情

相关推荐

Unity Scriptable Build Pipeline (SBP) 详解

Unity 的可编程构建管线(Scriptable Build Pipeline, SBP)标志着引擎构建架构的一次关键转变,它从不透明的 C++ 实现转向了灵活、可扩展的 C# 框架。SBP 旨在满足现代游戏开发日益增长的需求,通过改进增量处理和高效缓存机制显著提升了构建性能。它赋予开发者对内容构建过程前所未有的控制力,从而能够针对特定项目需求进行深度定制。尽管 SBP 是 Unity 推荐的 Addressables 系统的重要基础层,但理解其核心组件、构建流程和高级功能对于优化大型项目、简化 CI/C

m0_57771536的博客 2209

Go 知识点(07)— 对已经关闭通道进行读写

今天我们来看下对已经关闭通道进行读写会发生什么情况。 1. 对已关闭通道进行写操作 看下面代码会输出什么结果? func main() { ch := make(chan string, 1) close(ch) ch <- "hello, world" fmt.Println(<-ch) } 输出结果为: panic: send on closed channel 这个结果无论对于非缓冲通道还是缓冲通道都是一样的,即对已经关闭的通道进行写操作,会触发 panic 。 2. 对已关闭

wohu1104的专栏 3078

从动态规划到最优控制:Hamilton-Jacobi-Bellman (HJB) 方程的核心思想与应用

本文深入解析了Hamilton-Jacobi-Bellman (HJB) 方程的核心思想与应用,从动态规划到最优控制的演变过程。通过实际案例展示了HJB方程在机器人路径规划、工业机械臂优化等领域的实践价值,并探讨了数值求解方法和深度学习结合的神经HJB前沿进展。

weixin_28700411的博客 458

【go】chan的阻塞和panic操作

chan的阻塞和panic情况

weixin_40660221的博客 725

【YOLO11改进 - 注意力机制】SCSA通过结合空间注意力和通道注意力,提高各种下游视觉任务的性能。

【YOLO11改进 - 注意力机制】SCSA通过结合空间注意力和通道注意力,提高各种下游视觉任务的性能。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 475

多思计组实验实验三、存储器读写实验

实验三、存储器读写实验

qq_53089329的博客 3653

golang channel关闭后,是否可以读取剩余的数据

golang channel关闭后,其中剩余的数据,是可以继续读取的。 请看下面的测试例子。 创建一个带有缓冲的channel,向channel中发送数据,然后关闭channel,最后,从channel中读取数据,输出结果。 package main import ( "fmt" ) func main(){ ch := make(chan int, 3) ...

翔云 1万+

安装anaconda3时出现错误:Failed to link extracted packages to D:\anaconda!...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1483

记录一次[panic: send on closed channel]错误

主线程创建并初始化 channel ,开启多线程操作 k8s 创建 pvc、pv,主线程阻塞;程序在线程 xx 中创建 pvc 失败,线程报错,将错误信息输入到 channel 中,主线程接收到 channel 并报错。

weixin_44276313的博客 905

20、基于图神经网络的脱氢焓预测方法研究

本文研究了基于图神经网络(GNN)的液态有机氢载体(LOHC)材料脱氢焓预测方法。通过分析现有GNN方法的局限性,提出了一种新的聚合自节点表示(AWS)方法,并结合丰富的原子特征和集成学习策略,显著提高了预测性能。实验结果表明,AWS在脱氢焓预测和多个基准化学性质预测任务中均优于现有GNN方法。此外,基于分子结构的集成方法进一步提升了模型的鲁棒性和准确性。研究展示了该方法在筛选LOHC材料中的潜力,并为未来预测更多化学性质奠定了基础。

pp12345的博客 103

昇腾AI原生创新算子挑战赛(S1赛季)复盘-LessEqual算子

【代码】昇腾AI原生创新算子挑战赛(S1赛季)复盘-LessEqual算子。

william_myq的博客 509

Go Channel 详解

Go Channel 详解

淡淡忧桑 8352

深入理解SQL注入中的union select 1,2,3....

UNION 用于合并两个查询的结果集

渗透之路,攻防之间皆学问 2万+

Golang channel 死锁的几种情况以及例子

Golang channel 死锁的几种情况以及例子 死锁是指两个或两个以上的协程的执行过程中,由于竞争资源或由于彼此通信而造成的一种阻塞的现象,若无外力作用,他们将无法推进下去,以下是总结出来的几种死锁情况。 1.死锁1:一个通道在一个主go程里同时进行读和写 2.死锁2:go程开启之前使用通道 3.死锁3 :通道1中调用了通道2,通道2中调用通道1 4.死锁4:直接读取空channel的死锁 5.死锁5:超过channel缓存继续写入数据导致死锁 6.向已关闭的channel中写入数据不会导致死锁,但是

Chen_Jeep的博客 3052

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

小厂golang面经

在Go语言中,slice是一种动态数组结构,当向slice添加元素时如果容量不足,底层会触发扩容机制。扩容时,新的容量通常是原容量的两倍,同时会分配一块新的内存区域并将原有数据复制过去。如果原容量足够大,则不会触发扩容。首先明确slice是由一个底层数组支持的动态视图,它包含三个关键属性:指向底层数组的指针、当前长度和容量。当我们对slice进行append操作时,如果当前长度加上新增元素数量超过容量,就会触发扩容。

weixin_54385104的博客 539

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Go语言Channel遍历方法

先来看看基本的定义: channel是Go语言中的一个核心类型,可以把它看成管道。并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度。channel是一个数据类型,主要用来解决go程的同步问题以及协程之间数据共享(数据传递)的问题。 (1)channle 本质上是一个数据结构——(队列),数据是先进先出。(2)具有线程安全机制,多个go程访问时,不需要枷锁...

weixin_42117918的博客 2万+

Golang中nil channel妙用

改进后的示例程序的最关键变化是在判断c1或c2被关闭后,显式地将c1或c2置为nil。我们知道,对一个nil channel执行获取操作,该操作将被阻塞,因此已经被置为nil的c1或c2的分支将再也不会被select选中执行。对于没有初始化的channel进行读写操作将会发生阻塞。此测试程序目的是依次输出5和7两个数字后退出,但是实际输出结果是在输出5之后,程序输出了许多0后才输出7并退出。但是nil channel并非一无是处,有时候妙用nil channel可以达到事半功倍的效果。

weixin_43710037的博客 425

golang的channel使用

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34390105的博客 212

go channel总结

1、创建 无缓冲var chs1 = make(chan int)var chs2 = make(chan float64)var chs3 = make(chan string)有缓冲var chs1 = make(chan int, 3)var chs2 = make(chan float64, 3)var chs3 = make(chan string, 3) 有缓冲和无缓冲的...

dklg36635的博客 207

Golang之channel讲解

总之,Go语言中的channel是一种用于在goroutine之间进行通信和同步的机制,可以避免共享内存的问题,从而使并发编程更加简单和安全。其中,data_type是channel中传输的数据类型,ch是创建的channel变量。可以将channel作为参数传递给goroutine,它们可以同时读写channel,从而实现数据的交换和同步。Channel可以避免共享内存的问题,从而避免了多线程之间的竞争和死锁等问题,使得并发编程更加简单和安全。其中,ch是channel变量,data是接收到的数据。

mujingluo的博客 531

golang踩坑--channel的正确使用姿势

一、为什么要用channel 笔者也是从Java转Go的选手,之前一直很难摆脱线程池、可重入锁、AQS等数据结构及其底层的思维定式。而最近笔者也开始逐渐回顾过往的实习和实验,慢慢领悟了golang并发的一些经验了。 golang在解决并发race问题时,首要考虑的方案是使用channel。可能很多人会喜欢用互斥锁sync.Mutex,因为mutex lock只有Lock和Unlock两种操作,与Java中的ReentrantLock比较类似。但笔者实践过程中发现: 互斥锁只能做到阻塞,而无法让流程之间通信

weixin_43829117的博客 2486

golang channel笔记

管道基本介绍 channel本质是一个数据队列 数据是先进先出 FIFO 本身是线程安全的,多线程访问时不需要加锁 有类型的,一个string的channel只能存放string类型数据 定义和声明

weixin_45161636的博客 435

Golang复习笔记之Channel、context

若等待接收队列 recvq 不为空,则缓冲区中无数据或无缓冲区,将直接从 recvq 取出 G ,并把数据写入,最后把该 G 唤醒,结束发送过程。若等待发送队列 sendq 不为空,且没有缓冲区,直接从 sendq 中取出 G ,把 G 中数据读出,最后把 G 唤醒,结束读取过程。如果等待发送队列 sendq 不为空,说明缓冲区已满,从缓冲区中首部读出数据,把 G 中数据写入缓冲区尾部,把 G 唤醒,结束读取过程。若缓冲区中有空余位置,则将数据写入缓冲区,结束发送过程。并发控制神器之Context。

weixin_55985119的博客 407

goroutine之间的通信——channel

引入 在多线程的那篇博客中,我们可以注意点,每一段代码的最后都会有这样一段代码: var s string fmt.Scan(&s) 这段代码的含义就是等待输入,那究竟是为什么需要这一段代码呢? 如果去掉了这一段代码,在屏幕上并不会输出任何东西。 因为,这个进程(主线程)创建完两个线程之后就关闭了,同时两个刚刚创建的线程,还得队列里没有运行的线程只能和主线程一起被关闭。 那有没有什么办法使得线程在运行完之后,告诉进程(主线程)它已经运行完了,然后进程(主线程)再关闭呢? 这里就引出了Golang

lijf2001的博客 686

GO语言-管道channel

GO语言-channel通道

qq522044637的博客 600

golang学习笔记26-管道(Channel)【重要】

本节也是GO核心部分,很重要。介绍了管道的读数据,写数据,关闭,遍历操作,协程和管道如何协同工作,管道的只读/只写声明,select多路复用,for监听管道。

技术卷的博客 1549

Go并发编程——channel

以前从未接触过并发编程,所以,且写且学吧

luan_tianjiao的专栏 1590
上一篇: Golang io/ioutil包源码分析
下一篇: linux journalctl使用详解
思维的深度
博客等级 码龄11年 2万+粉丝 391原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值