Go 语言进阶与依赖管理

news/2024/4/27 12:57:10/文章来源:https://blog.csdn.net/myf_666/article/details/128868097

作者:非妃是公主
专栏:《Golang》
博客主页:https://blog.csdn.net/myf_666
个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩
在这里插入图片描述

文章目录

  • 一、语言进阶
    • 1. 并发和并行
    • 2. 协程(Goroutine)与线程
    • 3. CSP(Communicating Sequential Processes)
    • 4. Channel
    • 5. 并发安全 Lock
    • 6. WaitGroup
  • 二、依赖管理
    • 1. GOPATH
    • 2. Go Vendor
    • 3. Go Module
      • Ⅰ. 依赖表述
      • Ⅱ. 依赖管理
      • Ⅲ. 本地工具
        • ① go get
        • ② go mod

在这里插入图片描述

一、语言进阶

1. 并发和并行

Go语言是一种并发性能很好的语言,它可以多核(多核指:一个电脑包含多个CPU)优势,更加高效地运行。
在这里插入图片描述


2. 协程(Goroutine)与线程

Go语言的并发编程,主要就是通过协程(Goroutine)来实现的。协程和线程类似,但又并不同于线程,它比线程更加轻量级。
在这里插入图片描述

协程:用户态,轻量级线程,栈KB级别;
线程:内核态,线程跑多个协程,栈MB级别。


3. CSP(Communicating Sequential Processes)

协程间通信与进程通信类似,主要有2种方式:

  1. 通道
  2. 临界区

对于这两种方式,Go语言采用第一种——通道方式,进行协程间的信息传递。即,下图中左边的这种方式:
在这里插入图片描述
这样做的优点是,通过通信共享内存性能较高,不会像临界区一样,存在性能较低的问题。

4. Channel

缓冲通道:

  • 无缓冲通道 make(chan int)
  • 有缓冲通道 make(chan int,2)

它可以采用上面make的方式进行初始化,第一个参数指定类型,第二个参数指定缓冲通道的大小。

在这里插入图片描述

一个示例代码如下:

package concurrencefunc CalSquare() {src := make(chan int)dest := make(chan int, 3)go func() {defer close(src)for i := 0; i < 10; i++ {src <- i}}()go func() {defer close(dest)for i := range src {dest <- i * i}}()for i := range dest {//复杂操作println(i)}
}

代码中关于defer主要用来进行延迟调用(程序执行完毕后,即将退出时,执行defer,详细的关于defer的介绍,请查看博客:Golang中的一些关键字),然后相当于通过src这一公共区域进行内存通信。

这个demo程序类似于生产者、消费者进程,输出结果如下:

在这里插入图片描述

5. 并发安全 Lock

锁的作用主要是用来保证在操作变量时,只有一个协程在操作,这时候另一个协程想要操作的时候,需要等待锁解除才行。这样的操作,可以保证程序执行的正确性,防止程序出错。

下面来看一个demo,这个demo的作用是执行2000次+1操作,然后采用5个协程进行。函数的定义如下。

首先,是带有锁的函数定义,在操作x的时候,锁住了lock,如下:

func addWithLock() {for i := 0; i < 2000; i++ {lock.Lock()x += 1lock.Unlock()}
}

不带锁的定义,如下:

func addWithoutLock() {for i := 0; i < 2000; i++ {x += 1}
}

5个协程,每个执行2000次+1操作,如下:

func Add() {x = 0for i := 0; i < 5; i++ {go addWithoutLock()}time.Sleep(time.Second)println("WithoutLock:", x)x = 0for i := 0; i < 5; i++ {go addWithLock()}time.Sleep(time.Second)println("WithLock:", x)
}

运行程序如下:

在这里插入图片描述

这时,很有意思的是,并没有发生错误!本来想着由于没有加锁,这样多个进程在操作数据的时候就可能在同一个时钟周期,而造成数据丢失。

于是,我分析了一下原因,现在的CPU为16核,甚至更多,5个协程可能可以在不同的不同核上并行去跑,之间并没有影响。也就是说,会不会出错误,可能和机子的性能有关。我的机子是16核的,因此,我进行了如下尝试,修改协程数为17,果然,触发了错误,没有锁的协程产生了操作丢失。

在这里插入图片描述

6. WaitGroup

相当于一个计数器,那么它的作用是什么呢?记录当前正在执行的协程数,当正在执行的线程数不为 0 的时候,就需要进行一个等待。

demo程序如下:

func ManyGoWait() {var wg sync.WaitGroupwg.Add(5)for i := 0; i < 5; i++ {go func(j int) {defer wg.Done()hello(j)}(i)}wg.Wait()
}

其中 wg 表示创建的一个WaitGroup,通过Add可以添加一个协程数,Add可以为负数;

然后启动协程,通过延迟调用,当协程完成后,我们执行Done函数,这会对写成书 -1 。

最后通过 Wait 函数,如果正在运行的协程不为0(存在正在运行的协程),那么就不结束主进程。

关于WaitGroup的定义,可以查看源码及注释进行了解,如下:
在这里插入图片描述

Done 和 Wait,如下:

在这里插入图片描述

同时,有了 wg.Wait() ,既可以省略了之前的 time.Sleep(time.Second) 了。

二、依赖管理

随着功能的增强,同时也需要更多的依赖库,这时候,依赖管理就显得很重要了。

Golang的依赖管理按照发展历史,可分为3种,GOPATH,Go Vendor,Go Module。如下图:

在这里插入图片描述

1. GOPATH

首先,值得说明的是,不同于Java、C++、python等,在Golang中,是不存在项目(project)这一概念的,在Gopath路径下就是Golang的工作目录,存在三个文件夹,作用分别如图中标注:

在这里插入图片描述

弊端:无法实现package的多版本控制。比如,不同的程序用到了同一个package,但是又是不同版本的,这时候,Gopath这种管理方式就无法处理了。如下:

在这里插入图片描述

2. Go Vendor

由于上面的弊端,诞生了Go Vendor,相当于在每个项目下,建立了一个Vendor文件夹,里面存放项目中用到的package,当程序寻找依赖报的时候,先去Vendor中去寻找,如果找不到,再去Gopath下去寻找,这就避免了上面提到的 package版本 问题。
在这里插入图片描述

但这种方法同样存在着较大的问题,如果一个项目(A)用到的两个包(B和C),这两个包又依赖了同一个包D,但是用到的这同一个包但是版本不同且不兼容的包D,同样回出现如下 无法控制版本 的问题(即项目内出现此问题):

在这里插入图片描述

3. Go Module

Go Module解决了上面相同包,不同版本的问题。

和Mave很类似,其中包含三要素:

  1. 配置文件,描述依赖 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 go get/mod

Ⅰ. 依赖表述

在这里插入图片描述

在这里插入图片描述

通过上面这两种标识,我们就可以将不同版本的包区分开来。

Ⅱ. 依赖管理

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Ⅲ. 本地工具

① go get

在这里插入图片描述

② go mod

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Ubuntu20.04软件安装大全

目录 Ubuntu20.04 软件安装大全前言1. Windows和Ubuntu双系统安装1.1 下载Ubuntu系统镜像1.2 磁盘分区1.3 GPT分区安装Ubuntu1.4 系统完成后的一些设置1.5 遇到的一些小bug 2. 换源2.1 apt换源2.2 pip换源 3. 显卡驱动安装3.1 卸载显卡驱动3.2 准备工作3.3 驱动安装3.4 验证 4.…

Python自动发送消息小脚本,可用于各种聊天框~

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,YOLO,活动领域博主爱笑的男孩。擅长深度学习,YOLO,活动,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typecollect 个…

2023-04-23 算法面试中常见的动态规划问题

动态规划 1 什么是动态规划 以菲波那切数列求和为例&#xff0c;通过 1.普通的递归2.引入记忆数组memo3.自下而上地解决问题&#xff0c;即动态规划 动态规划的定义 dynamic programming (also known as dynamic optimization) is a method for solving a complex problem by…

C嘎嘎~~ 【初识C++ 下篇】

初识C 下篇 1.引用1.1引用的概念1.2引用的特点1.3常引用1.4引用使用的场景1.5引用和指针的区别 2.指针空值 --- nullptr3.内联函数3.1 内联函数的概念3.2内联函数的使用场景3.3内联函数的特性 1.引用 1.1引用的概念 相信大家小时候&#xff0c; 肯定有小名、绰号、亲朋好友的昵…

Zuul源码解析(二)

Zuul 的自动配置 ZuulProxyAutoConfiguration 如何触发 如上图&#xff0c;在 spring.factory 中配置 ZuulProxyAutoConfiguration 自动配置了&#xff0c;直接点进去 如上图所示&#xff0c;发现这有个条件注解&#xff0c;需要有 org.springframework.cloud.netflix.zuul.Zu…

“支付+SaaS”赋能传统产业数字化转型

易观&#xff1a;传统支付业务利润空间在政策监管和市场竞争下不断被压缩&#xff0c;多家上市支付机构逐步将业务经营重点转移切入到企业交易环节&#xff0c;为企业提供包括SaaS服务、行业解决方案、营销服务及金融科技服务等在内的企业服务收入成为新的增长点。 伴随着“十四…

Linux网络服务之yum仓库

目录 一、yum仓库简介二. ftp搭建yum源三. 搭建国内在线源四. 本地源和在线yum同时使用五. 通过缓存的方式保存所下载的软件包六 . 制作yum仓库 一、yum仓库简介 yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红帽软件包管理器的缩写&#xff09;构建的软件更新机…

Java入门教程||Java 继承||Java 重写(Override)与重载(Overload)

Java 继承 继承是所有 OOP 语言和 Java 语言不可缺少的组成部分。 继承是 Java 面向对象编程技术的一块基石&#xff0c;是面向对象的三大特征之一&#xff0c;也是实现软件复用的重要手段&#xff0c;继承可以理解为一个对象从另一个对象获取属性的过程。 如果类 A 是类 B …

Automa自动化爬取文本(一)

目录 介绍 下载地址 安装教程 爬取百度热搜 介绍 Automa 是一个免费、开源的 Chrome 扩展&#xff0c;它通过目前流行的 No Code 无代码方式&#xff0c;只需要拖拽模块就实现了浏览器自动化&#xff0c;比如自动填写表格、执行重复性任务。 在工作中&#xff0c;如果我们…

learn_C_deep_5 (语句和表达式的概念、if语句的多种语法结构、C语言有没有布尔类型、“零值”的比较)

目录 语句和表达式的概念 if语句的多种语法结构 注释的便捷方法&#xff08;环境vs&#xff09; if语句执行的过程 逻辑与&& 逻辑或|| 运算关系的顺序 ​编辑 C语言有没有布尔类型 C99标准 sizeof(bool)的值为多少&#xff1f; _Bool原码 BOOL、TRUE、…

ERTEC200P-2 PROFINET设备完全开发手册(9-2)

9.2 运行AC1/AC4参考代码 修改源代码usrapp_cfg.h的宏为 #define EXAMPL_DEV_CONFIG_VERSION 44 编译后下载到评估板运行AC4示例程序 在TIA中导入GSDML-V2.35-Siemens-ERTEC200pApp44-20210623.xml。新建项目&#xff0c;添加PLC和Devkit设备。 按照如下图所示配置模块&am…

基于vfw的局域网语音聊天室系统源码论文

语音视频聊天 UDP套接字的运用 在实现语音视频聊天时,采用的是基于UDP套接字的点对点模式,而UDP面向的是无连接的数据服务,其套接字的使用如图10所示。 图10 UDP套接字的使用 视频的捕获 利用VFW接口&#xff0c;视频捕获可以分为以下几个步骤&#xff1a; 建立视频采集窗口…

stm32在SDIO模式下SD写入错误的问题

1、问题描述 使用FAT32 f_write 多次执行写操作时&#xff0c;会报FR_DISK_ERR错误&#xff0c;而且是刚开始写不报错&#xff0c;写几次后会一直报错。 设断点跟踪到HAL_SD_WriteBlocks中&#xff0c;在调用SDMMC_CmdWriteMultiBlock时&#xff0c;会报SDMMC_ERROR_TX_UNDERR…

【MYSQL】Java的JDBC编程(idea连接数据库)

1. 配置 &#xff08;1&#xff09;新建一个项目 &#xff08;2&#xff09;Build System 那里选择Maven,下一步Create &#xff08;3&#xff09;配置pom.xml文件 首先查看自己的MYSQL版本&#xff1a;进入MySQL命令窗口 我的MYSQL版本是8.0版本的. 下一步&#xff0c;…

C/C++占位符,%x和%p的区别

遇到的问题 今天遇到了一个很奇怪的问题&#xff0c;当使用malloc分配了一个堆空间后&#xff0c;分别尝试用cout和printf尝试打印该地址&#xff0c;出现了两个地址不一样的情况&#xff1a; int *pp (int*)malloc(10*sizeof(int)); *pp 1234; cout << pp << …

常用数据加密

一、加密和解密 1、 加密 数据加密的基本过程&#xff0c;就是对原来为明 的文件或数据按某种算法进行处理&#xff0c;使其成为不可读的一段代码&#xff0c;通常称为 “密文”。通过这样的途径&#xff0c;来达到保护数据不被 非法人窃取、阅读的目的。 2、解密 加密的逆…

2023年,人工智能和数据训练呈现哪些新趋势?

最近&#xff0c;多才多艺的“全能网友”ChatGPT一次次火出圈。未来人工智能将以多快的速度、发展到何种地步&#xff1f;人们已经开始坐下来认真地探讨和思考。 我们生活在这个日新月异的时代。新的一年&#xff0c;人工智能的真正能力和应用场景又发生了哪些演进&#xff1f;…

Java性能优化之序列化优化

1、Java 序列化及其缺陷 Java 提供了一种序列化机制&#xff0c;这种机制能够将一个对象序列化为二进制形式&#xff08;字节数组&#xff09;&#xff0c;用于写入磁盘或输出到网络&#xff0c;同时也能从网络或磁盘中读取字节数组&#xff0c;反序列化成对象&#xff0c;在程…

java Excel清除表格条件格式规则

© Ptw-cwl 目录 文章目录 目录Excel清除表格条件格式规则1.开始 -> 条件格式2.条件格式 -> 清除规则3.管理规则也能删除 代码报java.lang.IllegalArgumentException: Specified CF index 43 is outside the allowable range (0..42)如何解决源码 Excel清除表格条件…

GitHub 开源神器 Bark模型,让文本转语音更简单

今天跟大家分享一个文本转语音的开源模型&#xff1a;Bark Bark 是由Suno创建的基于转换器的文本到音频模型。Bark 可以生成高度逼真的多语言语音以及其他音频 - 包括音乐、背景噪音和简单的音效。该模型还可以产生非语言交流&#xff0c;如大笑、叹息和哭泣。 该项目刚开源不…