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

Go语言现代web开发14 协程和管道

概述

Concurrency is a paradigm where different parts of the program can be executed in parallel without impact on the final result. Go programming supports several concurrency concepts related to concurrent execution and communication between concurrent executions.

并发是一种范例,其中程序的不同部分可以并行执行而不会影响最终结果。Go编程支持与并发执行和并发执行之间的通信相关的几个并发概念。

协程

A thread is a small sequence of instructions that can be processed by a single CPU core. Moder hardware architectures have multiple cores, so we can execute multiple threads in paralle.

线程是可以由单个CPU核心处理的一小段指令序列。现代硬件架构有多个内核,因此我们可以并行执行多个线程。

Go programming language offers its own solution for concurrent execution, called goroutines. Goroutines can be defined as lightweight threads (because they are very small, only a couple of KB will be used to store all thread-related data on the stack) managed by Go routine.

Go编程语言为并发执行提供了自己的解决方案,称为gooutines。Go例程可以定义为由Go例程管理的轻量级线程(因为它们非常小,只需要几个KB就可以将所有与线程相关的数据存储在堆栈上)。

If we use the go keyword in front of a function call, that function will be executed in a new goroutine, but the evaluation of arguments will be executed in the current goroutine. Here we have two function calls, the first one will be executed in the current goroutine and for the second one, a new goroutine will be created.

如果我们在函数调用前使用go关键字,那么该函数将在新的运行例程中执行,但参数的计算将在当前运行例程中执行。这里我们有两个函数调用,第一个将在当前的运行例程中执行,第二个将创建新的运行例程。

sendMessage(message1)
go sendMessage(message2)

Goroutines run in the same address space so, in certain situations, goroutines must synchronize memory access and communicate with each other.

运行在相同的地址空间中,因此,在某些情况下,运行例程必须同步内存访问并相互通信。

完整示例代码:

package mainimport ("fmt""time"
)func sendMessage(msg string) {fmt.Println(msg)
}func main() {sendMessage("hello, Mara!")// main goroutine 一旦执行结束,其他goroutine不再执行,被迫结束go sendMessage("Hi, Mara!")// 方法1:延长main的执行时间time.Sleep(time.Second)
}

管道

We can define the channel as a construct through which we can send and receive values. In order to send or receive value, we will use the <-(arraow) operator in the following way:

  • ch <- value will send value to channel ch
  • value = <- ch will receive value from channel ch

我们可以将管道定义为可以发送和接收值的构造。为了发送或接收值,我们将以以下方式使用<-(箭头)操作符:

  • ch <- value 将发送值到管道ch
  • value = <- ch 将从管道ch接收值

As can be seen, the data flow is determined by the direction of the arrow.

可以看出,数据流是由箭头方向决定的。

We have two types of channels:

  • Unbuffered without buffer for message storage
  • Buffered with buffer for message storage

我们有两种管道:

  • 不带缓存的管道,没有缓存存储消息
  • 带缓存的管道,通过缓存存储消息

By default, the channel is unbuffered with send and receive as blocking operations. The sender will be blocked until the receiver is ready to pick up the variable from the channel and vice versa. The receiver will be blocked, waiting for the value until the sender sends it to the channel. This can be very useful because there is no need for any additional synchronization.

默认情况下,管道是无缓冲的,发送和接收都是阻塞操作。发送方将被阻塞,直到接收方准备好从通道中获取变量,反之亦然。接收方将被阻塞,等待该值,直到发送方将其发送到通道。这非常有用,因为不需要任何额外的同步。

Traditionally, we use the make() function to create a channel. This will create a new channel that allows us to send and receive string variables.

传统上,我们使用make()函数来创建管道。下面的示例将创建一个允许我们发送和接收字符串变量的新管道。

ch := make(chan string)

Through the channels which we have dealt so far, we can send only one value. But in practice, this is not an acceptable solution, for example, if the sender is faster than the receiver, the sender will be blocked too often. We can avoid that by defining a buffer, now we can accept more variables. Channels with buffers are called buffered channels.

对于我们刚才创建的管道,我们只能发送一个值。但在实践中,这不是一个可接受的解决方案,例如,如果发送方比接收方快,发送方就会经常被阻塞。我们可以通过定义缓冲区来避免这种情况,现在我们可以接受更多的变量。具有缓冲区的通道称为缓冲通道。

A buffered channel will be created by adding buffer size as a second parameter in the make() function.

通过在make()函数中添加缓冲区大小作为第二个参数来创建缓冲通道。

ch = make(chan string, 100)

With the buffered channel, the sender will be blocked only when the buffer is full and the receiver will be blocked only when the buffer is full and the receiver will be blocked only when the buffer is empty. In the next code example, we will use the bufferedchannel to send two messages from new goroutines and receive those messages in the main goroutine.

对于缓冲通道,只有当缓冲区已满时发送方才会被阻塞,只有当缓冲区为空时接收方才会被阻塞。在下一个代码示例中,我们将使用bufferedchannel从新的运行例程发送两条消息,并在主运行例程中接收这些消息。

func sendMessage(message string, ch chan string) {ch <- message
}func main() {ch := make(chan string, 2)go sendMessage("Hello", ch)go sendMessage("World", ch)fmt.Println(<-ch)fmt.Println(<-ch)
}

We cannot influence which goroutine will send the message first, words Hello and World will not always be displayed in that order on standard output.

我们无法影响哪个程序将首先发送消息,单词Hello和World在标准输出中并不总是按该顺序显示。

The sender and only the sender can close the channel when there are no more values to send by calling the close() function.

当没有更多的值可以发送时,只有发送方可以通过调用close()函数关闭通道。

close(ch)

The receiver should check if the channel is closed. In the following expression, variable ok will have the value false when the channel is closed.

接收端应该检查信道是否关闭。在下面的表达式中,当通道关闭时,变量ok的值为false。

v ok <- ch

Constant checking an be tiresome, but luckily, a special kind of for range loop can be used. If we put the channel in for range, the loop will receive values until the channel is closed.

不断的检查是令人厌烦的,但幸运的是,一种特殊的范围循环可以使用。如果我们将通道设置为for range,循环将接收值,直到通道关闭。

for v := range ch {fmt.Println(v)
}

If we try to send a message to a closed channel, panic will be triggered. When panic occurs, a message will be displayed on standard output and the function where panic has occurred with crash.

如果我们试图向封闭通道发送信息,就会引发panic异常。当panic发生时,将在标准输出和发生panic的函数上显示一条消息并崩溃。

In all of our previous examples, the receiver waits on only one channel, but Go provides us with the concept that allows the receiver to wait on multiple channels: select statement. Syntatically, select statement is similar to be switch statement, with one differece, keyword select is used instead of keyword switch. The receiver will be blocked until one of the case statements can be executed.

在前面的所有示例中,接收方只在一个通道上等待,但是Go为我们提供了select语句,允许接收方在多个通道上等待。从语法上讲,select语句与switch语句类似,区别在于使用关键字select而不是关键字switch。接收方将被阻塞,直到其中一个case语句可以执行。

select{case <- ch1:fmt.PPrintln("Channel One")case <- ch2:fmt.Println("Channel Two")default:fmt.Println("Waiting")
}

A default case will be executed if no other case isready.

如果没有准备好其他情况,将执行默认情况。

相关文章:

Go语言现代web开发14 协程和管道

概述 Concurrency is a paradigm where different parts of the program can be executed in parallel without impact on the final result. Go programming supports several concurrency concepts related to concurrent execution and communication between concurrent e…...

Llama3.1的部署与使用

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 什么是Llama3.1&#xff1f; Llama3.1 是 Meta&#xff08;原 Facebook&#xff09;公…...

Java/Spring项目的包开头为什么是com?

Java/Spring项目的包开头为什么是com&#xff1f; 下面是一个使用Maven构建的项目初始结构 src/main/java/ --> Java 源代码com.example/ --->为什么这里是com开头resources/ --> 资源文件 (配置、静态文件等)test/java/ --> 测试代码resourc…...

深度学习自编码器 - 随机编码器和解码器篇

序言 在深度学习领域&#xff0c;自编码器作为一种无监督学习技术&#xff0c;凭借其强大的特征表示能力&#xff0c;在数据压缩、去噪、异常检测及生成模型等多个方面展现出独特魅力。其中&#xff0c;随机编码器和解码器作为自编码器的一种创新形式&#xff0c;进一步拓宽了…...

Spring IoC DI

Spring 框架的核心是其控制反转&#xff08;IoC&#xff0c;Inversion of Control&#xff09;和依赖注入&#xff08;DI&#xff0c;Dependency Injection&#xff09;机制。这些概念是为了提高代码的模块化和灵活性&#xff0c;进而简化开发和测试过程。下面将详细介绍这两个…...

[数据集][目标检测]无人机飞鸟检测数据集VOC+YOLO格式6647张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6647 标注数量(xml文件个数)&#xff1a;6647 标注数量(txt文件个数)&#xff1a;6647 标注…...

Vue 中 watch 的使用方法及注意事项

前言 Vue 的 Watch 是一个非常有用的功能&#xff0c;它能够监听 Vue 实例数据的变化并执行相应的操作。本篇文章将详细介绍 Vue Watch 的使用方法和注意事项&#xff0c;让你能够充分利用 Watch 来解决 Vue 开发中的各种问题。 1. Watch 是什么&#xff1f; 1.1 Watch 的作…...

情指行一体化平台建设方案和必要性-———未来之窗行业应用跨平台架构

一、平台建设必要性 以下是情指行一体化平台搭建的一些必要性&#xff1a; 1. 提高响应速度 - 实现情报、指挥和行动的快速协同&#xff0c;大大缩短从信息获取到决策执行的时间&#xff0c;提高对紧急情况和突发事件的响应效率。 2. 优化资源配置 - 整合各类资源信…...

窗口框架frame(HTML前端)

一.窗口框架 作用&#xff1a;将网页分割为多个HTML页面&#xff0c;即将窗口分为多个小窗口&#xff0c;每个小窗口可以显示不同的页面&#xff0c;但是在浏览器中是一个完整的页面 基本语法 <frameset cols"" row""></frameset><frame…...

51单片机——数码管

一、数码管原理图 我们发现&#xff0c;总共有8个数码管。 它们的上面接8个LED&#xff0c;用来控制选择哪个数码管。例如要控制第三个数码管&#xff0c;就让LED6为0&#xff0c;其他为1&#xff0c;那LED又接到哪呢&#xff1f; 二、LED 由图可以看出&#xff0c;这个一个1…...

`re.compile(r“(<.*?>)“)` 如何有效地从给定字符串中提取出所有符合 `<...>` 格式的引用

regexp re.compile(r"(<.*?>)") 这行代码是在Python中使用正则表达式的一个示例&#xff0c;具体含义如下&#xff1a; re.compile(): 这个函数来自Python的 re&#xff08;正则表达式&#xff09;模块&#xff0c;用于将一个正则表达式模式编译成一个正则表…...

算法打卡:第十一章 图论part01

今日收获&#xff1a;图论理论基础&#xff0c;深搜理论基础&#xff0c;所有可达路径&#xff0c;广搜理论基础&#xff08;理论来自代码随想录&#xff09; 1. 图论理论基础 &#xff08;1&#xff09;邻接矩阵 邻接矩阵存储图&#xff0c;x和y轴的坐标表示节点的个数 优点…...

为C#的PetaPoco组件增加一个批量更新功能(临时表模式)

总有一些数据是需要批量更新的&#xff0c;并且更新的字段&#xff0c;每个数据都不一样。 为了实现这样一个功能&#xff0c;写了这样一个方法&#xff1a; using System.Linq.Expressions; using System.Reflection; using System.Text; using NetRube.Data; using PetaPoc…...

Spring实战——入门讲解

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 Spring介绍 Spring实战的入门讲解主要涵盖了Spring框架的基本概念、核心功能以及应用场景。以下是关于Spring实战入门的具体介绍&#xff1a; Spring框架概述&#xff1a;Spring是一个轻量级的Java开发框架…...

MTK芯片机型的“工程固件” 红米note9 5G版资源预览 写入以及改写参数相关步骤解析

小米机型:小米5 小米5x 米6 米6x 米8 米9 米10系列 米11系列 米12系列 mix mix2 mix2s mix3 max max2 max3 note3 8se 9se cc9系列 米play 平板系列等分享 红米机型:红米note4 红米note4x 红米note5 红米note6 红米note7 红米note8 红米note8pro 红米s2 红米note7pro 红米…...

[Golang] Context

[Golang] Context 文章目录 [Golang] Context什么是context创建context创建根context创建context context的作用并发控制context.WithCancelcontext.WithDeadlinecontext.WithTimeoutcontext.WithValue 什么是context Golang在1.7版本中引入了一个标准库的接口context&#xf…...

【JAVA集合总结-壹】

文章目录 synchronized 的实现原理以及锁优化&#xff1f;ThreadLocal原理&#xff0c;使用注意点&#xff0c;应用场景有哪些&#xff1f;synchronized和ReentrantLock的区别&#xff1f;说说CountDownLatch与CyclicBarrier 区别Fork/Join框架的理解为什么我们调用start()方法…...

Mysql梳理7——分页查询

目录 7、分页查询 7.1 背景 7.2 实现规则 分页原理 7.3 使用 LIMIT 的好处 7、分页查询 7.1 背景 背景1&#xff1a;查询返回的记录太多了&#xff0c;查看起来很不方便&#xff0c;怎么样能够实现分页查询呢&#xff1f; 背景2&#xff1a;表里有 4 条数据&#xff0c…...

智能制造与工业互联网公益联播∣企企通副总经理杨华:AI的浪潮下,未来智慧供应链迭代方向

近两年在IT圈子里面&#xff0c;AI毫无疑问是最火的一个词语&#xff0c;最近的ChatGPT、文心一言、通义千问&#xff0c;从千亿参数到万亿参数&#xff0c;再往前就是Sora文生视频异军突起... 在人工智能的浪潮下&#xff0c;AI之于供应链的价值体现在哪些地方&#xff1f;其发…...

《深度学习》—— 卷积神经网络(CNN)的简单介绍和工作原理

文章目录 一、卷积神经网络的简单介绍二、工作原理(还未写完)1.输入层2.卷积层3.池化层4.全连接层5.输出层 一、卷积神经网络的简单介绍 基本概念 定义&#xff1a;卷积神经网络是一种深度学习模型&#xff0c;通常用于图像、视频、语音等信号数据的分类和识别任务。其核心思想…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...