golang特性3

golang特性

通过通信共享内存

在 Go 中,通信共享内存是通过通道来实现的。Go 语言的设计哲学之一就是“不要通过共享内存来通信,而应通过通信来共享内存”。这意味着不鼓励直接在多个协程之间共享内存,而是通过通道进行数据交换,以确保并发安全性。

应用场景

  • 协程间通信,即协程间数据传递
  • 并发场景下利用channel的阻塞机制,作为同步机制(类似队列)
  • 利用channel关闭时发送广播的特性,作为协程退出通知

任务分发与结果收集: 可以使用一个或多个协程生成任务,并将这些任务发送到一个通道中,然后另一个或多个协程从该通道接收任务并执行。执行结果可以发送到另一个通道中,由另一个协程负责收集和处理
生产者-消费者模型: 可以使用通道来实现生产者-消费者模型,其中一个或多个协程负责生成数据并将其发送到通道中(生产者),另一个或多个协程从通道中接收数据并进行处理(消费者)。
协程池: 可以使用通道来实现协程池,其中一个协程负责接收任务并将其发送到通道中,另一个或多个协程从通道中接收任务并执行。
同步任务并行执行: 可以使用通道来控制多个协程的执行顺序,通过在通道中发送信号来同步它们的执行
资源访问控制可以使用通道来控制对共享资源的访问,例如使用一个带有缓冲区的通道作为互斥锁,只有当通道中有空间时才允许写入,否则阻塞。
协程退出通知: 使用通道的关闭机制可以作为一种通知机制,当一个协程需要通知其他协程退出时,可以关闭一个通道,其他协程通过检测通道关闭来得知退出的信号,从而安全地结束执行。
使用通道实现并发安全的共享内存的基本示例:

package mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroupch := make(chan int)wg.Add(2)// 协程1:向通道发送数据go func() {defer wg.Done()for i := 0; i < 5; i++ {ch <- i // 将数据发送到通道}close(ch) // 关闭通道}()// 协程2:从通道接收数据go func() {defer wg.Done()for num := range ch { // 从通道接收数据,直到通道被关闭fmt.Println("Received:", num)}}()wg.Wait()
}

创建了一个通道 ch,用于在两个协程之间传递数据。协程1负责向通道发送数据,协程2负责从通道接收数据。通道的阻塞特性确保了在数据发送和接收之间的同步,而通道的关闭机制则用于结束数据传递的过程。

channel 通过通讯共享内存

通道本质上是一种类型安全的消息队列,用于在协程之间传递数据。通过使用通道,可以避免并发环境下的竞态条件和锁问题,提高代码的可读性和可维护性。

通道的使用方式很简单:可以通过内置函数make()来创建一个通道,然后通过<-运算符来发送和接收数据。通道可以是有缓冲的,也可以是无缓冲的,具体选择取决于应用场景。

  1. channel的方向,读、写、读写
  2. channel 协程间通信信道
  3. channel 阻塞协程
  4. channel 并发场景下的同步机制
  5. channel 通知协程退出
  6. channel 的多路复用
package mainimport ("fmt""time"
)func sender(ch chan<- int) {for i := 0; i < 5; i++ {ch <- i // 将数据发送到通道time.Sleep(time.Second)}close(ch) // 关闭通道
}func receiver(ch <-chan int) {for {val, ok := <-ch // 从通道接收数据if !ok {fmt.Println("通道已关闭")return}fmt.Println("接收到数据:", val)}
}func main() {ch := make(chan int) // 创建一个整型通道go sender(ch)go receiver(ch)time.Sleep(6 * time.Second) // 等待一段时间确保程序执行完毕
}

sender函数负责往通道发送数据,而receiver函数负责从通道接收数据。主函数创建了一个通道,并启动了两个协程来执行发送和接收操作。

通过通道,这两个协程之间就实现了数据的传递,而不需要显式地共享内存。这种通信方式更加安全和可靠,避免了并发编程中常见的竞态条件和死锁问题。
安全可靠的原因
这种通过通道进行通信的方式更加安全和可靠,主要是因为它遵循了以下几个原则:
基于消息传递的通信模型:通道是基于消息传递的通信模型,它强调的是发送方和接收方之间的解耦。发送方通过通道将数据发送给接收方,而不需要关心接收方何时会收到数据,接收方也无需关心数据是何时发送的。这种解耦的特性减少了代码之间的耦合度,使得代码更加清晰和易于理解。
内置的同步机制:通道在实现上具有内置的同步机制,发送操作和接收操作都是原子性的当一个协程尝试向通道发送数据时,如果通道已满(对于有缓冲的通道),发送操作会被阻塞,直到有接收方从通道中接收数据为止;同样,如果一个协程尝试从通道接收数据时,如果通道为空,接收操作也会被阻塞,直到有发送方向通道发送数据为止。这种阻塞机制有效地避免了竞态条件的发生。
关闭通道和广播特性通道支持关闭操作,可以通过close()函数关闭通道。当通道关闭后,接收方可以通过判断通道的关闭状态来知道是否还有数据可以接收,这样就避免了接收方因为等待数据而陷入死锁状态。另外,关闭通道时会触发广播机制,所有正在等待接收数据的协程都会被唤醒,从而可以及时退出或进行其他操作
通过通道进行通信的方式更加安全和可靠,因为它提供了简单且有效的同步机制,避免了常见的并发编程问题,如竞态条件和死锁。同时,它也符合 Go 语言的设计理念,即“不要通过共享内存来通信,而是通过通信来共享内存”,使得代码更加清晰、易于理解和维护。

注意

channel 用于协程间通讯,必须存在读写双方,否则将造成死锁

果一个通道没有发送方或接收方,就无法完成通信操作。例如,如果一个协程试图向一个没有接收方的通道发送数据,发送操作将永远被阻塞,导致该协程无法继续执行下去,从而产生死锁。同样地,如果一个协程试图从一个没有发送方的通道接收数据,接收操作也将永远被阻塞,同样会导致死锁。

因此,在使用通道进行协程间通信时,需要确保发送方和接收方的存在,并且它们能够正确地协调完成数据的发送和接收操作,以避免死锁的发生。
在Go中,可以使用内置的len和cap函数来确定通道的发送方和接收方是否存在。

使用len(ch)函数可以检查通道中当前排队的元素数量。如果通道为空(没有发送方),则len(ch)返回0。
使用cap(ch)函数可以检查通道的容量。如果通道是无缓冲的(容量为0),则它必须有一个接收方,否则发送操作将被阻塞。如果通道是有缓冲的,即容量大于0,那么即使没有接收方,发送操作也可能不被阻塞,因为缓冲区中可以存放一定数量的元素。

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

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

相关文章

C语言.指针(4)

指针&#xff08;4&#xff09; 1.回调函数是什么&#xff1f;2.qsprt使用举例2.1使用qsort函数排序整型数据2.2使用qsort函数排序结构体数据 3.qsort函数的模拟实现 1.回调函数是什么&#xff1f; 回调函数就是一个通过函数指针调用的函数 如果你把函数的指针&#xff08;地址…

Java集合体系面试题

1. Java中有哪些主要的集合接口&#xff1f; 答案&#xff1a;Java中主要的集合接口有Collection、List、Set、Queue和Map。 2. 请解释List和Set之间的主要区别。 答案&#xff1a;List和Set的主要区别在于元素的顺序和唯一性。List是有序的集合&#xff0c;允许存储重复的元…

PHP安装swoole拓展

一&#xff1a;下载swoole拓展 PHP的swoole拓展下载地址&#xff1a;https://pecl.php.net/package/swoole wget http://pecl.php.net/get/swoole-4.2.12.tgz二&#xff1a;安装swoole拓展 1&#xff1a;解压swoole拓展包 tar xzvf swoole-4.2.12.tgz cd swoole-4.2.122&am…

pandas(day6 图表)

一. 计算效率 1. 测量代码运行时间 %%time %%timeit 单纯计算 代码块执行的时长 %%time _sum(np.arange(6)) CPU times: total: 0 ns Wall time: 1.66 ms用于多次运行代码块并计算平均执行时间 %%timeit _sum(np.arange(6))738 ns 10.7 ns per loop (mean std. dev. of 7…

java常用设计模式介绍及代码示例

设计模式是在软件设计中发现、研究和应用的一种有效方法。设计模式并不直接转化成代码&#xff0c;而是提供了解决某一问题的框架。下面介绍一些常用的设计模式以及对应的Java代码示例&#xff1a; 1. 单例模式&#xff1a;确保某一个类只有一个实例&#xff0c;同时提供一个访…

java流式计算Stream

java流式计算Stream 流(Stream)到底是什么呢? 是数据渠道&#xff0c;用于操作数据源&#xff08;集合、数组等&#xff09;所生成的元素序列。 “集合讲的是数据&#xff0c;流讲的是计算! ” 特点&#xff1a; Stream自己不会存储元素。 Stream不会改变源对象。相反&#x…

金三银四面试题(十六):MySQL面试都问什么(1)

在开发岗位面试中&#xff0c;MySQL基本是必考环节。所以接下来我们就进入MySQL八股文环节&#xff0c;看看都有哪些高频考题。 MySQL 中有哪些不同的表格&#xff1f; 在MySQL中&#xff0c;可以创建多种不同类型的表格&#xff0c;其中一些常见的类型包括&#xff1a; InnoD…

代码随想录第18天: 二叉树part05

力扣513 找树左下角的值 class Solution {public int findBottomLeftValue(TreeNode root) {Queue<TreeNode> que new LinkedList<>();que.offer(root);int res 0;while(!que.isEmpty()) {int size que.size();for(int i 0; i < size; i) {TreeNode tmp q…

Git(8)之分支间同步特定提交

Git(8)之分支间同步特定提交 Author&#xff1a;Once Day Date&#xff1a;2024年4月7日 漫漫长路有人对你微笑过嘛… 全系列文章可查看专栏: Git使用记录_Once_day的博客-CSDN博客 文章目录 Git(8)之分支间同步特定提交1. 分支间同步提交2. cherry-pick同步分支间的特定提交…

docker打包haproxy并代理web或mysql集群

1、需求&#xff1a; 使用haproxy代理两个服务&#xff08;web服务或者是mysql服务&#xff09; 2、编写Dockerfile 2.1、创建Dockerfile专用目录 mkdir /docker/images/haproxy -p && cd /docker/images/haproxy 2.2、下载软件包到Dockerfile专用目录 curl -O h…

性能优化-如何爽玩多线程来开发

前言 多线程大家肯定都不陌生&#xff0c;理论滚瓜烂熟&#xff0c;八股天花乱坠&#xff0c;但是大家有多少在代码中实践过呢&#xff1f;很多人在实际开发中可能就用用Async&#xff0c;new Thread()。线程池也很少有人会自己去建&#xff0c;默认的随便用用。在工作中大家对…

ThingsBoard通过MQTT发送属性数据

MQTT基础 客户端 MQTT连接 属性上传API 案例 MQTT基础 MQTT是一种轻量级的发布-订阅消息传递协议&#xff0c;它可能最适合各种物联网设备。 你可以在此处找到有关MQTT的更多信息&#xff0c;ThingsBoard服务器支持QoS级别0&#xff08;最多一次&#xff09;和QoS级别1&…

3D打印技术引领压铸模具制造新变革

随着工业4.0浪潮的席卷&#xff0c;3D打印技术以其独特优势&#xff0c;正逐渐成为新一轮工业革命中的璀璨明星。这一技术不仅为“中国制造”向“中国智造”的转型提供了强大动力&#xff0c;也为压铸模具这一铸造行业的重要分支带来了前所未有的变革。 压铸模具&#xff0c;作…

文心一言指令词宝典之咨询分析篇

作者&#xff1a;哈哥撩编程&#xff08;视频号、抖音、公众号同名&#xff09; 新星计划全栈领域优秀创作者博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏&#xff1a; &#x1f3c5;…

深入浅出理解ArrayBuffer对象TypedArray和DataView视图

目录 举例理解 1. ArrayBuffer对象 2. TypedArray 3. DataView 总结 具体讲解 1. ArrayBuffer对象 2. TypedArray 3. DataView 注意事项 举例理解 先举个简单的例子理解ArrayBuffer对象TypedArray和DataView视图的概念和之间的关系 1. ArrayBuffer对象 想象一个场景…

2024.2.17力扣每日一题——N叉树的层序遍历

2024.2.17 题目来源我的题解方法一 广度优先搜索&#xff08;队列实现&#xff09; 题目来源 力扣每日一题&#xff1b;题序&#xff1a;429 我的题解 方法一 广度优先搜索&#xff08;队列实现&#xff09; 和二叉树的层序遍历相同&#xff0c;只是在添加子节点的细节有所不…

NAT网络地址转换原理解析

NAT&#xff08;Network Address Translation&#xff09;&#xff0c;即网络地址转换&#xff0c;是一种在1994年提出的地址转换技术。它的主要目的是在本地网络中使用私有地址&#xff0c;在连接互联网时转而使用全局IP地址。NAT实际上是为解决IPv4地址短缺而开发的技术。NAT…

MBTI测试背后的心理学原理:为什么它能揭示你的职业性格?(包含开源免费的API接口)

MBTI简介 迈尔斯-布里格斯类型指标&#xff08;Myers–Briggs Type Indicator&#xff0c;MBTI&#xff09;是由美国作家伊莎贝尔布里格斯迈尔斯和她的母亲凯瑟琳库克布里格斯共同制定的一种人格类型理论模型。 该指标以瑞士心理学家卡尔荣格划分的8种心理类型为基础&#xff…

[算法前沿]--022-使用 StarCoder 创建一个编程助手

文章目录 StarCoder调优测试StarCoder BigCode 开发的 StarCoder,这是一个在一万亿的 token、80 多种编程语言上训练过的 16B 参数量的模型。训练数据多来自 GitHub 上的 issues、使用 Git 提交的代码、Jupyter Notebook 等等 。得益于对企业友好的许可证、长度为 8192 的 to…

Mojo编程语言案例及介绍

Mojo是一种新兴的编程语言&#xff0c;它结合了现代编程范式与简洁易读的语法&#xff0c;为开发者提供了一个强大且高效的开发工具。以下将详细介绍Mojo编程语言的特性&#xff0c;并通过一个实际案例来展示Mojo的应用。 一、Mojo编程语言介绍 Mojo编程语言的设计理念是“简单…