go Channel原理 (四)

Channel

设计原理

不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。

在主流编程语言中,多个线程传递数据的方式一般都是共享内存。
在这里插入图片描述
Go 可以使用共享内存加互斥锁进行通信,同时也提供了一种不同的并发模型,即通信顺序进程(Communicating sequential processes,CSP)。Goroutine 和 Channel 分别对应 CSP 中的实体和传递信息的媒介,Goroutine 之间会通过 Channel 传递数据。在这里插入图片描述
上图中的两个 Goroutine,一个会向 Channel 中发送数据,另一个会从 Channel 中接收数据,它们两者能够独立运行并不存在直接关联,但是能通过 Channel 间接完成通信。

关闭 channel

func closechan(c *hchan) {// 关闭一个 nil channel,panicif c == nil {panic(plainError("close of nil channel"))}// 上锁lock(&c.lock)// 如果 channel 已经关闭if c.closed != 0 {unlock(&c.lock)// panicpanic(plainError("close of closed channel"))}// …………// 修改关闭状态c.closed = 1var glist *g// 将 channel 所有等待接收队列的里 sudog 释放for {// 从接收队列里出队一个 sudogsg := c.recvq.dequeue()// 出队完毕,跳出循环if sg == nil {break}// 如果 elem 不为空,说明此 receiver 未忽略接收数据// 给它赋一个相应类型的零值if sg.elem != nil {typedmemclr(c.elemtype, sg.elem)sg.elem = nil}if sg.releasetime != 0 {sg.releasetime = cputicks()}// 取出 goroutinegp := sg.ggp.param = nilif raceenabled {raceacquireg(gp, unsafe.Pointer(c))}// 相连,形成链表gp.schedlink.set(glist)glist = gp}// 将 channel 等待发送队列里的 sudog 释放// 如果存在,这些 goroutine 将会 panicfor {// 从发送队列里出队一个 sudogsg := c.sendq.dequeue()if sg == nil {break}// 发送者会 panicsg.elem = nilif sg.releasetime != 0 {sg.releasetime = cputicks()}gp := sg.ggp.param = nilif raceenabled {raceacquireg(gp, unsafe.Pointer(c))}// 形成链表gp.schedlink.set(glist)glist = gp}// 解锁unlock(&c.lock)// Ready all Gs now that we've dropped the channel lock.// 遍历链表for glist != nil {// 取最后一个gp := glist// 向前走一步,下一个唤醒的 gglist = glist.schedlink.ptr()gp.schedlink = 0// 唤醒相应 goroutinegoready(gp, 3)}
}
  1. 关闭状态 closed 值为 1。
  2. 将 recvq 和 sendq 中所有正在阻塞的 gorountine 唤醒。sender 直接 panic,receiver 返回一个相应类型的零值。

channel 的使用,有几点不方便的地方:
3. 在不改变 channel 自身状态的情况下,无法获知一个 channel 是否关闭。
4. 关闭一个 closed channel 会导致 panic。
5. 向一个 closed channel 发送数据会导致 panic。

由于关闭一个 cloed 的 channel 或者由 sender 关闭 channel 会导致panic,所以关闭 channel 应该是:
6. channel 不手动关闭由 gc 代劳。
7. 由 sender 关闭并确保只关闭一次(比如 sync.Once)。

channel 发送和接收元素的本质

All transfer of value on the go channels happens with the copy of value.

channel 的发送和接收操作本质上都是值的拷贝。无论是从 sender goroutine 的栈到 chan buf,还是从 chan buf 到 receiver goroutine,或者是直接从 sender goroutine 到 receiver goroutine。

channel 在什么情况下会引起资源泄漏

channel 可能会引发 goroutine 泄漏。
泄漏的原因是 goroutine 操作 channel 后,处于发送或接收阻塞状态,而 channel 处于满或空的状态,一直得不到改变。同时,垃圾回收器也不会回收此类资源,进而导致 gouroutine 会一直处于等待队列中。
程序运行过程中,对于一个 channel,如果没有任何 goroutine 引用了,gc 会对其进行回收操作,不会引起内存泄漏。

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

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

相关文章

试用笔记之-VB微信支付支付宝支付源代码

首先下载VB微信支付&支付宝支付源代码 http://www.htsoft.com.cn/download/VB6WeiXin_ZhiFuBao_ZhiFu.rar

【一念发动便是行】念头,就是命运

一个个恶念累积就是负能量,念头就是命运,克除恶念,防范念头,念头都有能量,学圣学须内外庄严检肃,言语有灵 多数人的问题都是出在念头上,念头,就是自己的命运; 当我们对自…

Linux--信号(万字详解!超完整!)

目录 0.预备知识 0.1.基本概念 0.2.信号的捕捉 0.3.理解信号的发送与保存 1.信号的产生(阶段一) 1.通过kill命令,向指定进程发送指定的信号 2.通过终端按键产生信号:ctrlc(信号2),ctrl\(…

【python】PyQt5控件尺寸大小位置,内容边距等API调用方法实战解析

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

第十二章 执行引擎

一、执行引擎概述 概述 执行引擎是 Java 虚拟机核心的组成部分之一。“虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引…

AlmaTech股份有限公司如何通过有效的营销本地化解锁全球市场

在当今全球化经济中,企业必须调整营销策略,以引起不同地区不同受众的共鸣。营销本地化,包括定制营销材料以满足各种市场的文化、语言和监管要求,对于实现这一目标至关重要。本案例研究探讨了领先的电子商务公司AlmaTech股份有限公…

解锁水利智慧:智慧水利的深度剖析与未来展望,探讨智慧水利如何助力水利行业实现数字化转型与智能化升级

本文关键词:智慧水利、智慧水利工程、智慧水利发展前景、智慧水利技术、智慧水利信息化系统、智慧水利解决方案、数字水利和智慧水利、数字水利工程、数字水利建设、数字水利概念、人水和协、智慧水库、智慧水库管理平台、智慧水库建设方案、智慧水库解决方案、智慧…

数据驱动下的SaaS渠道精细化运营:提升ROI的实战指南

在当今数字化转型的大潮中,SaaS(Software as a Service)企业面临着日益激烈的市场竞争。为了在市场中脱颖而出,实现可持续增长,SaaS企业必须转向更为精细化的运营模式,而数据驱动则是实现这一目标的关键。本…

TCP 的安全可靠

TCP的安全可靠 重传机制往返时间测量快速重传 流量控制拥塞控制 重传机制 T C P确认从另一端收到的数据以提供可靠的运输层,但数据和确认都有可能会丢失。 T C P通过在发送时设置一个定时器来解决这种问题。如果当定时器溢出时还没有收到确认,它就重传该…

【C++】认识使用string类

【C】STL中的string类 C语言中的字符串标准库中的string类string类成员变量string类的常用接口说明成员函数string(constructor构造函数)~string(destructor析构函数)默认赋值运算符重载函数 遍历string下标[ ]迭代器范围for反向迭代器 capacitysizelengthmax_sizeresizecapaci…

不错的用户需求访谈方法

不错的用户需求访谈方法,可以用如下的矩阵,用来引导用户访谈:

【C++】哈希表 ---开散列版本的实现

你很自由 充满了无限可能 这是很棒的事 我衷心祈祷你可以相信自己 无悔地燃烧自己的人生 -- 东野圭吾 《解忧杂货店》 开散列版本的实现 1 前言2 开散列版本的实现2.1 节点设计2.2 框架搭建2.3 插入函数2.4 删除函数2.5 查找操作2.6 测试 Thanks♪(・ω&#x…

python如何不保留小数

1、int() 向下取整(内置函数) n 3.75 print(int(n)) >>> 3 n 3.25 print(int(n)) >>> 3 2、round() 四舍五入(内置函数) n 3.75 print(round(n)) >>> 4 n 3.25 print(round(n)) >>> 3 …

SpringBoot实战:轻松实现XSS攻击防御(注解和过滤器)

文章目录 引言一、XSS攻击概述1.1 XSS攻击的定义1.2 XSS攻击的类型1.3 XSS攻击的攻击原理及示例 二、Spring Boot中的XSS防御手段2.1 使用注解进行XSS防御2.1.1 引入相关依赖2.1.2 使用XSS注解进行参数校验2.1.3 实现自定义注解处理器2.1.4 使用注解 2.2 使用过滤器进行XSS防御…

[单master节点k8s部署]18.监控系统构建(三)Grafana安装

Grafana是一个跨平台的开源的度量分析和可视化工具。支持多种数据源,比如OpenTSDB,Prometheus,ElasticResearch,Cloudwatch等。 Grafana安装 通过yaml配置grafana的pod和service,grafana工作在kube-system的命名空间…

C#(asp.net)房屋租赁管理系统-计算机毕业设计源码64421

目 录 摘要 1 绪论 1.1 研究背景与意义 1.2开发现状 1.3论文结构与章节安排 2 房屋租赁管理系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 …

标贝语音识别在智能会议系统的应用案例

语音识别是指将语音信号转换成文本或者其他数字信号形式的过程,随着人工智能在人们日常工作生活中的普及,语音识别技术也被广泛的应用在智能家居、智能会议、智能客服、智能驾驶等领域,以语音识别技术在智能会议系统中的应用为例,…

超高频RFID电子标签在服装供应链管理中的应用与优势

随着物联网技术的发展,RFID电子标签在服装行业中的应用越来越广泛。特别是超高频RFID电子标签,因其独特的优势,成为服装供应链管理的理想选择。本文将为您介绍超高频RFID电子标签的工作原理及其在服装供应链管理中的应用与优势。 超高频RFI…

Node之Web服务

前言 本文将讲解node的web服务 通过讲解http请求,node创建web服务等知识点让你更加深入的理解web服务和node创建的web服务 HTTP请求是什么? HTTP请求是客户端(通常是浏览器或其他应用程序)与服务器之间进行通信的一种方式。 …