百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Go语言入门必知教程-协程(go语言 入门)

liuian 2025-05-09 20:02 3 浏览

Golang中的并发性是指函数独立运行的能力。Goroutines就是能够并发运行的函数,也叫协程,它们是Golang提供作为并发处理操作的方法。

使用go语句创建协程goroutines

要将函数作为goroutine运行,以go语句为前缀调用函数。下面是示例代码块:

sum() // 正常的函数调用,该函数执行完返回后再执行下一条语句,这是同步调用

go sum() // 作为协程的函数调用,不等该函数执行完成直接执行下一条语句,这是异步调用

关键字go调用函数后立即返回,而函数作为协程在后台运行,程序的其余部分同时继续执行。每个Golang程序的main函数都是作为协程启动的,因此每个Golang程序至少运行一个goroutine。

创建协程

在每次调用函数responseSize之前添加go关键字。以下示例代码中有三个responseSize协程同时启动,对http.Get的三个调用也同时进行。程序不会等到一个响应返回后再发送下一个请求。因此,使用goroutines可以快速地打印三个响应的长度。

结果:

C:\Golang>go run main.go

Step1: https://www.baidu.com

Step1: https://www.sina.com.cn/

Step1: https://www.toutiao.com/

Step2: https://www.sina.com.cn/

Step3: https://www.sina.com.cn/

Step4: 116749

Step2: https://www.baidu.com

Step3: https://www.baidu.com

Step4: 79551

Step2: https://www.toutiao.com/

Step3: https://www.toutiao.com/

Step4: 203842

在main函数中添加了一个time.Sleep的方法,它可以防止main函数在协程结束之前退出。调用time.Sleep(10*time.Second)将使main协程睡眠10秒。

等待协程执行完成

sync包的中WaitGroup类型用来等待程序执行完所有在主函数中启动的协程。它维护一个记录协程数量的计数器,WaitGroup的Wait方法阻塞程序的执行,直到WaitGroup计数器为零,程序才继续往下执行。

调用WaitGroup的Add方法用于向WaitGroup添加计数器。

在协程里面使用defer语句调用WaitGroup的Done方法来减少WaitGroup计数器。

调用WaitGroup的Wait方法等待程序完成所有协程。

在主函数内部调用Wait方法,该方法阻止程序执行,直到WaitGroup计数器达到0的值,确保执行完所有协程。

结果:

C:\Golang>go run main.go

Start Goroutines

Step1: https://www.toutiao.com/

Step1: https://www.baidu.com

Step1: https://www.sina.com.cn/

Step2: https://www.sina.com.cn/

Step3: https://www.sina.com.cn/

Step4: 116749

Step2: https://www.baidu.com

Step3: https://www.baidu.com

Step4: 79801

Step2: https://www.toutiao.com/

Step3: https://www.toutiao.com/

Step4: 203842

从协程里获取值

从协程里获取值的最便捷的方法是通道。通道是连接并发性协程的管道。将值从一个协程里发送到通道中,另一个协程或同步函数再从通道里接收这些值。

结果:

C:\Golang>go run main.go

79655

运行和暂停协程的执行

使用管道可以运行和暂停协程的执行。管道就像是协程之间的协调者,用来进行这些操作。

结果:

1

2

3

4

Pause

Play

5

6

7

8

9

Stop

使用原子函数修复竞争条件

由于对共享资源的访问不同步,并试图同时对该资源进行读写,因此会出现竞争使用资源的情况。

原子函数提供同步访问整型和指针的低级锁定机制。原子函数通常用于修复竞争条件。

sync包中atomic子包的函数通过锁定对共享资源的访问来支持同步协程。


atomic包中的AddInt32函数通过强制一次只有一个协程可以执行和完成加法操作来同步整型值的更新。当协程试图调用任何atomic包的函数时,它们会自动地同步访问被限定的变量。

结果:

C:\Golang>go run -race main.go

Counter: 15

如果使用counter++代替atomic.AddInt32(&counter, 1),则结果如下:

C:\Golang>go run -race main.go

==================

WARNING: DATA RACE

Read at 0x0000006072b0 by goroutine 7:

main.increment()

C:/Golang/main.go:31 +0x76

Previous write at 0x0000006072b0 by goroutine 8:

main.increment()

C:/Golang/main.go:31 +0x90

Goroutine 7 (running) created at:

main.main()

C:/Golang/main.go:18 +0x7e

Goroutine 8 (running) created at:

main.main()

C:/Golang/main.go:19 +0x96

==================

Counter: 15

Found 1 data race(s)

exit status 66

使用互斥锁Mutex定义关键代码

互斥锁用于创建关键代码,关键代码内访问资源,从而确保一次只能有一个协程执行该部分代码。

结果:

C:\Golang>go run -race main.go

PHP stands for Hypertext Preprocessor.

PHP stands for Hypertext Preprocessor.

The Go Programming Language, also commonly referred to as Golang

The Go Programming Language, also commonly referred to as Golang

Counter: 4

由互斥锁的Lock()方法和Unlock()定义关键代码保护对计数器的更新。

相关推荐

GCI: Another key public good for international community

MembersofadelegationofhighschoolstudentsfromtheU.S.stateofWashingtonposeforaphotoa...

kube on kube 实现思路分享(kube-scheduler)

这里的kubeonkube,是指建立K8s元集群,纳管其他业务K8s集群,通过声明式API管理集群的创建、增删节点等。参考https://github.com/kubean-i...

China and India hold the key to a more inclusive global future

ByMayaMajueranLead:AsChinaandIndiamark75yearsofdiplomaticties,theircooperationcouldse...

日本真子公主的婚礼又要提上日程了吗?未婚夫:债务问题已解决

日本明仁天皇将于今年3月31日退位,德仁皇太子即将成为新一任的天皇。在平成时代最后的倒计时中,明仁天皇的孙女真子公主的婚事却又一次进入了人们的视野。(viaTheTelegraph)关注日本皇室的...

kratos源码分析系列(1)(kvm源码解析与应用 pdf)

https://github.com/go-kratos/kratos是b站开源的一个微服务框架,整体来看它结合grpc生态中的grpc-gateway,以及wire依赖注入和众多常用的trace,m...

【2.C#基础】6.循环语句(c#循环语句例子)

6.循环语句当需要多次执行同一个处理时,就需要用到循环语句。一般情况下,循环的流程图如下:6.1while循环C#中的while循环语句在给定的条件为真的情况下会重复执行目标语句。格式如下:...

使用 Google Wire 在 Go 中进行依赖注入

关注点分离、松耦合系统和依赖反转原则等概念在软件工程中是众所周知的,并且在创建良好的计算机程序过程中至关重要。在本文中,我们将讨论一个同时应用了这三个原则的技术,称为依赖注入。我们将尽可能地实践,更加...

用 Golang封装你的API(golang封装dll)
用 Golang封装你的API(golang封装dll)

每日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。@头条创作挑战赛本文探讨了在用Golang封装你的API的过程以及几个不同的编程步骤。我做了一个非常有限的时间来证明如何为客户正在开...

2025-05-09 20:03 liuian

Terraform 实战 | 万字长文(terrify是什么意思中文)

Terraform是什么Terraform(https://www.terraform.io/)是HashiCorp旗下的一款开源(Go语言开发)的DevOps基础架构资源管理运维工具,可...

Go 语言入门:环境安装(go语言安装 window)

一、前言这里不同于其他人的Go语言入门,环境安装我向来注重配置,比如依赖包、缓存的默认目录。因为前期不弄好,后面要整理又影响这影响那的,所以就干脆写成文章,方便后期捡起。二、安装1.安装包htt...

Go语言进阶之Go语言高性能Web框架Iris项目实战-项目结构优化EP05

前文再续,上一回我们完成了用户管理模块的CURD(增删改查)功能,功能层面,无甚大观,但有一个结构性的缺陷显而易见,那就是项目结构过度耦合,项目的耦合性(Coupling),也叫耦合度,进而言之,模块...

如何将Go项目与Docker结合实现高效部署

在现代软件开发中,使用Docker部署应用程序已经成为一种标准实践。本文将深入探讨如何将Go项目与Docker结合,实现高效、可靠的部署过程。通过详细的步骤和丰富的示例,你将能够迅速掌握这一流程。准备...

五分钟轻松熟悉一个k8s Operator应用制作

简介:operator是一种kubernetes的扩展形式,可以帮助用户以Kubernetes的声明式API风格自定义来管理应用及服务,operator已经成为分布式应用在k8s集群部...

程序员的副业秘籍!一款可以快速搭建各类系统的后台管理系统

系统简介这是一个基于Gin+Vue+ElementUI(或ArcoDesign、AntDesign)的系统快速开发平台,采用了前后端分离,旨在帮助用户快速完成各类系统的基础功能搭建。平...

使用 Go 语言开发区块链钱包的项目目录结构设计

在开发区块链钱包时,项目的目录结构应该清晰、模块化,确保代码的可维护性和扩展性。基于Go的惯例,结合区块链钱包的功能需求,以下是一个较为合理的目录结构示例:1.目录结构blockchain-wa...