golang goroutine(协程)和 channel(管道) 案例解析

news2025/4/28 8:06:47

文章目录

    • goroutine和channel概念
    • 开启线程与channel简单通信流程
    • 多个工作协程并发执行流程

goroutine和channel概念

  • goroutine(协程),一般我们常见的是进程,线程,进程可以理解为一个软件在运行执行的过程,线程跟协程比较类似,都是单独开辟一块内存,异步执行。不同的是协程占的内存比较小初始栈2KB左右。
  • channel(管道) , 管道实则也是用来存储数据的,那为什么不用切片呢,channel主要用于多个协程之间的通信同步,遵循的是先进先出,channel有容量的限制,如果说一直往里面存,不取的话那管道就会阻塞报错,所以合理处理管道数据,当数据处理完成后,要将管道关闭,不然后面如果要遍历channel时,就会一直等待channel关闭才会执行完成。

开启线程与channel简单通信流程

这里是使用了sync.awitGroup实现多协程异步执行,与channel进行通信过程。


//使用awitGroup用于阻塞主进程作用 等待所有协程执行完成,解除阻塞(类似于计数器,计数器为0,解除阻塞)
var wg sync.awitGroup

func printNum (ch chan int){
	for i :=1; i < 10 i++{
	   //循环将i添加到ch管道中,(channel为引用类型,可以直接修改源数据)
		ch <- i
     }
     //关闭管道 在后面我们如果要遍历处理管道数据时,不关闭则接收方会无线阻塞
     close(ch)
     //计数器减1
     wg.Done()
}

func readNum (ch chan int){
	//往ch管道中取数据 打印出来 ,channel时数据消耗性,只要读取了,这条数据不会在channel中保留、
   for v := range ch{
	  fmt,printIn(v)
   }
 }

 func main {
 	//创建一个channel管道,int类型,容量为10(缓冲区为10)
	ch:= make(chan int ,10)

	//计数器加1
	wg.add(1)
	//go关键字 开启一个协程 
	go printNum(ch)
	
	//计数器加1
	wg.add(1)
	//开启一个协程  协程与协程
	go readNum(ch)
    
    //阻塞主进程
    wg.awit()
	fmt.printIn("执行完成")
}

多个工作协程并发执行流程

处理100万个数字内那些是素数,这种数量大的情况下,循环创建多个工作协程,同时执行相关逻辑。

//使用awitGroup用于阻塞主进程作用 等待所有协程执行完成,解除阻塞(类似于计数器,计数器为0,解除阻塞)
var wg sync.awitGroup


func generateNumbers(inputChan chan int){
	for i :=2; i < 1000000 i++{
	   //循环将i添加到ch管道中,(channel为引用类型,可以直接修改源数据)
		inputChan  <- i
     }
     //关闭管道 在后面我们如果要遍历处理管道数据时,不关闭则接收方会无线阻塞
     close(ch)
     //计数器减1
     wg.Done()
}


func worker(inputChan chan int , outputChan chan int,exitChan chan int){
	//inputChan 管道中取数据 打印出来 ,channel是数据消耗性,只要读取了,这条数据不会在channel中保留、所以循环worker线程是随机值,是不可能多个工作线程执行一个数值
   	for num := range inputChan {
		flag := true
		for i := 2; i < num; i++ {
			// 判断如果不为素数 flag为false 则break跳出循环
			if num%i == 0 {
				flag = false
				break
			}
		 }
		 if flag {
			primeChan <- num //num 为素数 放在outputChan 管道中
		 }
	   }
    	// 标记减一  与wg.add(1) 配套使用
	    wg.Done()
	    // 因为worker需要多次执行 所以不能直接关闭outputChan 管道
	    // 向exitChan管道中写入数据 记录退出信号
	    exitChan <- true
 }


func listenWorker(exitChan chan int ,outputChan chan int){
	for i:=1; i < 16; i++{
	/*
	从oututChan中取数据,如果循环过程中执行的比工作协程快,没有取到数据,则会阻塞等待,
	直到outputChan中拿到数据,循环16次,全部协程执行完成。
     */
     <-outputChan
   }
   //关闭outputChan管道
   close(outputChan)
   //结束监听携程
   wg.Done()
}


 func main {
 	//存储100万个待处理数字
	inputChan:= make(chan int ,1000)
	//存素数的channel管道
	outputChan:= make(chan int 1000)
	//监听多协程结束的信号 容量为16,因为我们就开了16个协程,一般为cpu的逻辑处理器数量
	exitChan := make(chat bool 16)
	//计数器加1
	wg.add(1)
	//go关键字 开启一个协程 
	go generateNumbers(inputChan)
	
    // 创建工作协程
    numWorkers := runtime.NumCPU() // 协程数 = CPU 核心数
    for i := 0; i < numWorkers; i++ {
        go worker(inputChan, outputChan)
    }
	
	//如何关闭循环的多协程,第二种方案 再开一协程用于实时监听工作协程工作状态
	wg.add(1)
	go listenWorker(exitChan,outputChan)

    
    //阻塞主进程
    wg.awit()
     //如何关闭循环的多协程,第一种方案 在所有协程完成之后,关闭存素数的管道(outputChan)
	close(outputChan)
	fmt.printIn("执行完成")
}

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

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

相关文章

亚组风险比分析与可视化

1. 结果解读 1.1 风险比概述 1.1.1 风险比基本概念 风险比(Hazard Ratio)用于衡量治疗组与对照组事件发生的风险差异。 风险比为1,表示两组风险相同;小于1,治疗组风险低;大于1,治疗组风险高。 1.1.2 性别亚组分析 A性风险比小于1,表明治疗对A性有积极效果,风险降低。…

【博客系统】博客系统第一弹:博客系统项目配置、MyBatis-Plus 实现 Mapper 接口、处理项目公共模块:统一返回结果、统一异常处理

案例综合练习 - 博客系统 本节目标 从 0 到 1 完成博客系统后端项目的开发。 前言 通过前面课程的学习&#xff0c;我们掌握了 Spring 框架和 MyBatis 的基本使用&#xff0c;并完成了图书管理系统的常规功能开发。接下来我们系统地从 0 到 1 完成一个项目的开发。 项目介绍 …

基于OpenMV+STM32+OLED与YOLOv11+PaddleOCR的嵌入式车牌识别系统开发笔记

基于OpenMV、STM32与OLED的嵌入式车牌识别系统开发笔记 基于OpenMV、STM32与OLED的嵌入式车牌识别系统开发笔记系统架构全景 一、实物演示二、OpenMV端设计要点1. 硬件配置优化2. 智能帧率控制算法3. 数据传输协议设计 三、PyTorch后端核心实现&#xff1a;YOLOv11与PaddleOCR的…

w~嵌入式C语言~合集4

我自己的原文哦~ https://blog.51cto.com/whaosoft/13870376 一、STM32怎么选型 什么是 STM32 STM32&#xff0c;从字面上来理解&#xff0c;ST是意法半导体&#xff0c;M是Microelectronics的缩写&#xff0c;32表示32位&#xff0c;合起来理解&#xff0c;STM32就是指S…

K8S安全认证

一。用户认证的基本框架 在K8S集群中&#xff0c;客户端通常有两类&#xff1a; 1.User Account&#xff1a;一般独立于K8S之外的其他服务管理的用过户账号 2.Service Account&#xff1a;K8S管理的账号&#xff0c;用于为Pod中的服务进程在访问K8S提供身份标识 ApiServer是…

mybatis-plus里的com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析

以下是 com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析&#xff1a; 1. 类的作用 MybatisMapperProxy 是 MyBatis-Plus 框架中用于实现 Mapper 接口动态代理的核心类。它继承自 MyBatis 的 MapperProxy&#xff0c;并扩展了以下功能&#xff1a; …

在java程序中,类,进程,线程他们之间的关系以及main方法与他们之间的关系

在 Java 程序里&#xff0c;类、进程、线程各自有着不同的概念&#xff0c;同时也存在着紧密的联系&#xff0c;下面来详细分析它们之间的关系以及 main 方法和它们的关系。 类 类是 Java 中最基础的编程单元&#xff0c;是一种自定义的数据类型&#xff0c;它定义了对象的属…

[ACTF2020 新生赛]BackupFile题解

启动环境 进入后只有一段话&#xff0c;没有其他的说法。 解题方法 但是题目命名为backup file&#xff0c;应该是备份文件的意思&#xff0c;那么就用dirsearch工具来扫一下看看。 查看扫描结果 index.php.bak 下载下这个文件&#xff0c;查看文件内容。 进行php代码审计…

如何修改npm的全局安装路径?

修改 npm 的全局安装路径可以通过以下步骤完成&#xff0c;确保全局包&#xff08;使用 -g 安装的模块&#xff09;和缓存文件存储到自定义路径。以下是详细步骤&#xff1a; 1. 创建自定义路径的目录 在目标路径下创建两个文件夹&#xff0c;分别用于存储全局模块和缓存文件…

巧用 Element - UI 实现图片上传按钮的智能隐藏

引言 在前端开发中&#xff0c;使用 Element - UI 组件库来构建用户界面是非常常见的操作。其中图片上传功能更是在许多项目中频繁出现&#xff0c;比如用户头像上传、商品图片上传等场景。有时候&#xff0c;我们会有这样的需求&#xff1a;当上传图片达到一定数量后&#xf…

从“拼凑”到“构建”:大语言模型系统设计指南!

你有没有试过在没有说明书的情况下组装宜家家具?那种手忙脚乱却又充满期待的感觉,和设计大语言模型(LLM)系统时如出一辙。如果没有一个清晰的计划,很容易陷入混乱。我曾经也一头扎进去,满心期待却又手足无措,被网上那些复杂的架构图搞得晕头转向。于是,我坐下来,把它们…

【数据结构与算法】从完全二叉树到堆再到优先队列

完全二叉树 CBT 设二叉树的深度为 h , 若非最底层的其他各层的节点数都达到最大个数 , 最底层 h 的所有节点都连续集中在左侧的二叉树叫做 完全二叉树 . 特点 对任意节点 , 其右分支下的叶子节点的最底层为 L , 则其左分支下的叶子节点的最低层一定是 L 或 L 1 .完全二叉树…

【Linux网络】构建类似XShell功能的TCP服务器

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

Spring Boot 配置源详解(完整版)

Spring Boot 配置源详解&#xff08;完整版&#xff09; 一、配置源加载顺序与优先级 配置源类型优先级顺序&#xff08;从高到低&#xff09;对应配置类/接口是否可覆盖典型文件/来源命令行参数&#xff08;--keyvalue&#xff09;1&#xff08;最高&#xff09;SimpleComman…

puppeteer注入浏览器指纹过CDP

一、背景 通过puppeteer爬取目标网站时&#xff0c;经常会被对方网站检测到&#xff0c;比如原生puppeteerCDP特征非常明显&#xff0c;另外指纹如果一直不变&#xff0c;也会引发风控 二、实现 通过以下几行代码即可轻松过大部分检测点&#xff0c;并且能够切换指纹&#x…

软件项目实施全流程及交付物清单

需求分析 -> 概要设计 -> 详细设计 -> 开发实现 -> 测试 -> 部署 -> 运维 一、确认项目目标、范围和团队成员 二、收集和分析客户需求&#xff0c;确定需求规格 三、制定详细的项目计划&#xff0c;包括时间表、资源计划、预算 四、系统架构设计&#xf…

【2025计算机网络-面试常问】http和https区别是什么,http的内容有哪些,https用的是对称加密还是非对称加密,流程是怎么样的

HTTP与HTTPS全面对比及HTTPS加密流程详解 一、HTTP与HTTPS核心区别 特性HTTPHTTPS协议基础明文传输HTTP SSL/TLS加密层默认端口80443加密方式无加密混合加密&#xff08;非对称对称&#xff09;证书要求不需要需要CA颁发的数字证书安全性易被窃听、篡改、冒充防窃听、防篡改…

从梯度消失到百层网络:ResNet 是如何改变深度学习成为经典的?

自AlexNet赢得2012年ImageNet竞赛以来&#xff0c;每个新的获胜架构通常都会增加更多层数以降低错误率。一段时间内&#xff0c;增加层数确实有效&#xff0c;但随着网络深度的增加&#xff0c;深度学习中一个常见的问题——梯度消失或梯度爆炸开始出现。 梯度消失问题会导致梯…

Uni-App 多端电子合同开源项目介绍

项目概述 本项目是一款基于 uni-app框架开发的多端电子合同管理平台&#xff0c;旨在为企业及个人用户提供高效、安全、便捷的电子合同签署与管理服务。项目创新性地引入了 “证据链”与“非证据链”两种签署模式&#xff0c;满足不同场景下的签署需求&#xff0c;支持多种签署…