当前位置: 首页 > 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;通常用于图像、视频、语音等信号数据的分类和识别任务。其核心思想…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...

P10909 [蓝桥杯 2024 国 B] 立定跳远

# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上&#xff0c;小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时&#xff0…...

Yolo11改进策略:Block改进|FCM,特征互补映射模块|AAAI 2025|即插即用

1 论文信息 FBRT-YOLO&#xff08;Faster and Better for Real-Time Aerial Image Detection&#xff09;是由北京理工大学团队提出的专用于航拍图像实时目标检测的创新框架&#xff0c;发表于AAAI 2025。论文针对航拍场景中小目标检测的核心难题展开研究&#xff0c;重点解决…...

从数据报表到决策大脑:AI重构电商决策链条

在传统电商运营中&#xff0c;决策链条往往止步于“数据报表层”&#xff1a;BI工具整合历史数据&#xff0c;生成滞后一周甚至更久的销售分析&#xff0c;运营团队凭经验预判需求。当爆款突然断货、促销库存积压时&#xff0c;企业才惊觉标准化BI的决策时差正成为增长瓶颈。 一…...