当前位置: 首页 > news >正文

协程执行顺序引发的问题

引言

在Golang中,因为协程执行的顺序是不固定的,如果不在代码里进行控制,可能就会导致预期外的输出。
本文通过分析一段代码的执行来介绍这种情况,以及可行的控制协程执行顺序的方法:

  1. sleep()
  2. waitGroup

实例分析

代码

func NewRingBuffer(inCh, outCh chan int) *ringBuffer {return &ringBuffer{inCh:  inCh,outCh: outCh,}
}type ringBuffer struct {inCh  chan intoutCh chan int
}func (r *ringBuffer) Run() {for v := range r.inCh {select {case r.outCh <- v:default:<-r.outCh // pop one item from outchanr.outCh <- v}}close(r.outCh)
}func main() {inCh := make(chan int)outCh := make(chan int, 4)rb := pkg.NewRingBuffer(inCh, outCh)go rb.Run()for i := 0; i < 10; i++ {inCh <- i}close(inCh)//time.Sleep(time.Millisecond * 50)for res := range outCh {fmt.Println(res)}
}

上面代码的作用是,声明ringBuffer环状缓冲区;主协程往inCh写10个数的同时,有一个协程异步的读取数据,并写到outCh中;
outCh是一个4缓冲区大小的channel,如果outCh没满就直接写入,否则把outCh的首部元素移除再添加;
因此,预期输出应该是:6、7、8、9。
但实际的输出是:5、6、7、8、9。

分析

多出来的“5”,是因为协程的执行顺序不可控,当主协程执行到

for i := 0; i < 10; i++ {inCh <- i
}close(inCh)

时,此时outCh中是5、6、7、8;run协程还没有继续执行,就开始遍历outCh:

for res := range outCh {fmt.Println(res)
}

然后输出阻塞后,run协程才继续执行,把9写到outCh中,因此最后的输出结果是5、6、7、8、9.

解决办法

sleep()

使用sleep()函数,能让当前协程让出CPU,暂停执行一段时间。
对于这种方法,可以对上面函数进行如下改造:

close(inCh)
time.Sleep(time.Millisecond * 50)
// 新增
for res := range outCh {fmt.Println(res)
}

WaitGroup

使用waitGroup可以实现协程间通信,对于这段例子,通过wg保证run()函数执行完后,在对outCh进行输出。
改造方法如下:

func (r *ringBuffer) RunWithWg(wg *sync.WaitGroup) {defer wg.Done()for v := range r.inCh {select {case r.outCh <- v:default:<-r.outCh // pop one item from outchanr.outCh <- v}}close(r.outCh)
}func TestRaceWithWg(t *testing.T) {inCh := make(chan int)outCh := make(chan int, 4)rb := pkg.NewRingBuffer(inCh, outCh)var wg sync.WaitGroupwg.Add(1)go rb.RunWithWg(&wg)go func() {for i := 0; i < 10; i++ {inCh <- i}close(inCh)}()wg.Wait()for res := range outCh {fmt.Println(res)}
}

相关文章:

协程执行顺序引发的问题

引言 在Golang中&#xff0c;因为协程执行的顺序是不固定的&#xff0c;如果不在代码里进行控制&#xff0c;可能就会导致预期外的输出。 本文通过分析一段代码的执行来介绍这种情况&#xff0c;以及可行的控制协程执行顺序的方法&#xff1a; sleep()waitGroup 实例分析 代…...

android webview调用js滚动到指定位置

一、activity import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.tencent.smtt.sdk.WebView import com.tencent.smtt.sdk.WebViewClientclass MainActivity : AppCompatActivity() {private lateinit var webView: WebViewoverride fun …...

WPF 深入理解一、基础知识介绍

基础知识 本系列文章是对个人 B站 up 微软系列技术教程 记录 视频地址 https://www.bilibili.com/video/BV1HC4y1b76v/?spm_id_from333.999.0.0&vd_source0748f94a553c71a2b0125078697617e3 winform 与 wpf 异同 1.winform 项目结构 编辑主要是在 Form1.cs(页面)&#…...

腾讯云点播ugc upload | lack signature 问题处理

我犯一个很傻的错误 参考腾讯云官方文档&#xff1a;云点播 Web 端上传 SDK-开发指南-文档中心-腾讯云 进行开发&#xff0c;但是却报错了&#xff0c;始终找不到问题&#xff0c;错误提示&#xff1a;ugc upload | lack signature&#xff0c;意思是缺少签名或者签名失败&…...

计算机视觉实验二:基于支持向量机和随机森林的分类(Part one: 编程实现基于支持向量机的人脸识别分类 )

目录 一、实验内容 二、实验目的 三、实验步骤 四、实验结果截图 五、实验完整代码 六、报错及解决方案 PS:实验的运行速度受电脑性能影响,如遇运行卡顿请耐心等待。 一、实验内容 编程实现基于支持向量机的人脸识别分类,基本功能包括:Labeled Faces in th…...

5.什么是C语言

什么是 C 语言? C语言是一种用于和计算机交流的高级语言, 它既具有高级语言的特点&#xff0c;又具有汇编语言的特点 非常接近自然语言程序的执行效率非常高 C语言是所有编程语言中的经典&#xff0c;很多高级语言都是从C语言中衍生出来的&#xff0c; 例如:C、C#、Object-C、…...

DINO-DETR

DINO-DETR DETR收敛慢的问题1. Contrastive DeNoising Training(对比方法降噪训练)2. Mixed Query Selection(混合查询选择方法对锚点进行初始化)3. Look Forward Twice(两次前向方法)==DINO模型的传播过程,以及部分模块的改进==DETR收敛慢的问题 PnP-DETR(ICCV 2021) 改进了…...

Representation RL:HarmonyDream: Task Harmonization Inside World Models

ICML2024 paper code Intro 基于状态表征的model-based强化学习方法一般需要学习状态转移模型以及奖励模型。现有方法都是将二者联合训练但普遍缺乏对如何平衡二者之间的比重进行研究。本文提出的HarmonyDream便是通过自动调整损失系数来维持任务间的和谐&#xff0c;即在世界…...

Centos7系统下Docker的安装与配置

文章目录 前言下载Docker安装yum库安装Docker启动和校验配置Docker镜像加速卸载Docker 前言 此博客的内容的为自己的学习笔记&#xff0c;如果需要更具体的内容&#xff0c;可查看Docker官网文档内容 注意&#xff1a;以下命令在root管理员用户下运行&#xff0c;如果在普通用…...

无人机校企合作

有没有想过&#xff0c;无人机和校企合作能碰撞出怎样的火花&#xff1f;&#x1f525;今天就来给大家揭秘一下这个神秘组合&#xff01; 无人机&#xff0c;作为现代科技的代表&#xff0c;已经渗透到我们生活的方方面面。而校企合作&#xff0c;更是推动科技创新、培养人才的…...

八爪鱼现金流-028,个人网站访问数据统计分析,解决方案

个人网站访问数据统计分析&#xff0c;解决方案 调研 结论&#xff1a;使用百度统计 步骤 1.注册百度统计 2.获取安装代码 3.在项目中&#xff0c;页面代码添加如下片段 <script>var _hmt _hmt || [];(function() {var hm document.createElement("script&…...

大厂面试官问我:布隆过滤器有不能扩容和删除的缺陷,有没有可以替代的数据结构呢?【后端八股文二:布隆过滤器八股文合集】

往期内容&#xff1a; 面试官问我&#xff1a;Redis处理点赞&#xff0c;如果瞬时涌入大量用户点赞&#xff08;千万级&#xff09;&#xff0c;应当如何进行处理&#xff1f;【后端八股文&#xff08;1&#xff09;】-CSDN博客 本文为【布隆过滤器八股文合集】初版&#xff0c…...

PHP米表域名出售管理源码带后台

源码介绍 html5米表源码PHP域名销售程序安装方法&#xff1a; 本站已测试,各项功能正常,功能易用,不复杂,非常适合个人米表使用 1、所有文件传至网站目录 2、浏览器执行http://你的访问网址/install 3、输入mysql帐号及密码信息&#xff0c;提交安装 源码截图 源码下载 …...

【开发12年码农教你】Android端简单易用的SPI框架-——-SPA

Service(priority 1) public class APrinterService implements IPrinterService { Override public void print() { System.out.println(“this is a printer service.”); } } 复制代码 B模块 —— BPrinterService Service(path“b_printer”, priority 2) public class…...

以太坊==MetaMask获取测试币最新网址

估算分数https://community.infura.io/t/unable-to-receive-sepolia-eth-from-faucet/7715 Gitcoin Passport 水龙头地址&#xff0c;填入自己的测试地址 水龙头项目地址 GitHub - pk910/PoWFaucet: Modularized faucet for EVM chains with different protection methods (…...

军用FPGA软件 Verilog语言的编码准测之触发器、锁存器

军用FPGA软件 Verilog语言的编码准测之触发器、锁存器 语言 &#xff1a;Verilg HDL EDA工具&#xff1a;ISE、Vivado、Quartus II 军用FPGA软件 Verilog语言的编码准测之触发器、锁存器一、引言二、基本编程规范之触发器强制准则1---禁止在同一个 always 语句中混合使用有复位…...

智能汽车 UI 风格独具魅力

智能汽车 UI 风格独具魅力...

javafx例子笔记

文章目录 创建过程javafx独立版报错 Exception in thread "WindowsNativeRunloopThread" java.lang.NoSuchMethodError: <init> javafx是java gui工具。 一般会转换为exe&#xff0c;成为可交互的应用。 那么来个简单的例子吧。 先说明一点&#xff0c;javafx不…...

【ajax基础】回调函数地狱

一&#xff1a;什么是回调函数地狱 在一个回调函数中嵌套另一个回调函数&#xff08;甚至一直嵌套下去&#xff09;&#xff0c;形成回调函数地狱 回调函数地狱存在问题&#xff1a; 可读性差异常捕获严重耦合性严重 // 1. 获取默认第一个省份的名字axios({url: http://hmaj…...

SparkSQL的分布式执行引擎-Thrift服务:学习总结(第七天)

系列文章目录 SparkSQL的分布式执行引擎 1、启动Thrift服务 2、beeline连接Thrift服务 3、开发工具连接Thrift服务 4、控制台编写SQL代码 文章目录 系列文章目录前言一、SparkSQL的分布式执行引擎(了解)1、启动Thrift服务2、beeline连接Thrift服务3、开发工具连接Thrift服务4、…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...