学习golang(11) 初探:协程(2) 协程间通信

简介: 学习golang(11) 初探:协程(2) 协程间通信

协程基础请参考上一章,我们接着来看下协程后面的部分,协程间通信。



共享变量方式


我们协程间通信,可以采用共享变量的方式,不过得注意数据互斥,例如: 这里有一个小栗子,我们定义一个共享变量,赋初值为0,我们开启50个协程,每个协程对该值 +1,我们来看看具体效果。


image.png

我们执行程序后数据如下

image.png


为什么数据会不一样呢? 这是因为我们没有对result这个变量进行加,多个协程使用同一变量,但凡有一个协程用的是老的数据,执行结果也会修改最终值,所以才会导致这样的情况,为了避免这种情况,我们仅需对该函数加锁即可,例如: 我们将上述程序修改为如下


加入sync.Mutex ,修改程序如下

image.png


我们再次执行程序,数据如下

image.png


我们可以将上述加锁的关系简单理解为

image.png


除此之外,go sync还提供了另外一种锁sync.RWMutex,这是一种读写锁,适用于那些读多,写少。



管道方式

go中,协程间通信,很少用共享变量的方式,而更多的方式是使用管道,管道关键字chan


初探chan

我们一般使用make来申请管道,例如,我们申请一个不带缓存int类型的管道:

ch := make(chan int)


那么管道是如何进行读写的呢? go给我提供了相关方式

我们读写管道的内容是需要使用 <- ,例如,将管道的内容赋值给变量x

x := <-ch


例如,我们将3传入给管道ch

ch <- 3

对于不带缓存的管道,我们在未写入之前进行读取的话,会发生等待,例如如下例子。

image.png


执行结果

image.png

通过昨天学习协程可知,主协程中开启其他协程,当主协程执行完毕后,会关闭其他协程,为了避免协程未执行完被关闭,我们了解到第一种方式是加入计算量,例如:sync.WaitGroup ,其第二种方式便是使用管道,实际例子如上。



无缓冲chan 和 有缓冲chan

上述例子介绍的便是无缓冲chan,其申请方式为make(chan int) 或则make(chan int,0) ,而我们使用make申请的时候,其size 不为0,则申请的是有缓冲chan,二者区别为

无缓冲chan,在写入之前,读取会一直等待,而有缓冲chan在使用量 < size 则不会等待,而后会一直等待,对于有缓冲chan,我们可以使用 len来获取当前chan使用量,使用cap来获取总chan长度,例如:

image.png


我们执行代码后,可知

image.png

其他使用方法和无缓冲chan一致。



小案例

我们可以用管道来模拟一下生产者和消费者模型,例如,我们将模型规划为

image.png

我们使用管道,能够顺利写出这个demo


image.png


我们执行程序结果为

网络异常,图片无法展示
|



总结


管道(chan)作为我们常用的协程间通信方式之一,我们通常使用make来定义chan,类型可以分为有缓冲和无缓冲2种方式,对于有缓冲管道而言,我们可以写入多个值,直至len== cap容量则会等待,等待有操作向管道读取才会继续写入,通过上述案例就可以看得出,最后注意一旦,使用完管道后,要记得使用close 关闭掉。





相关文章
|
2月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
86 4
|
12天前
|
存储 安全 测试技术
GoLang协程Goroutiney原理与GMP模型详解
本文详细介绍了Go语言中的Goroutine及其背后的GMP模型。Goroutine是Go语言中的一种轻量级线程,由Go运行时管理,支持高效的并发编程。文章讲解了Goroutine的创建、调度、上下文切换和栈管理等核心机制,并通过示例代码展示了如何使用Goroutine。GMP模型(Goroutine、Processor、Machine)是Go运行时调度Goroutine的基础,通过合理的调度策略,实现了高并发和高性能的程序执行。
75 29
|
10天前
|
Go 计算机视觉
在Golang高并发环境中如何进行协程同步?
在此示例中,使用互斥锁来保护对共享计数器变量 c 的访问,确保并发的 HTTP 请求不会产生数据竞争。
31 3
|
10天前
|
负载均衡 算法 Go
GoLang协程Goroutiney原理与GMP模型详解
【11月更文挑战第4天】Goroutine 是 Go 语言中的轻量级线程,由 Go 运行时管理,创建和销毁开销小,适合高并发场景。其调度采用非抢占式和协作式多任务处理结合的方式。GMP 模型包括 G(Goroutine)、M(系统线程)和 P(逻辑处理器),通过工作窃取算法实现负载均衡,确保高效利用系统资源。
|
1月前
|
前端开发 Java API
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
本文是Vert.x学习系列的第五部分,讨论了回调函数的限制、Future和Promise在异步操作中的应用、响应式扩展以及Kotlin协程,并通过示例代码展示了如何在Vert.x中使用这些异步编程模式。
47 5
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
|
2月前
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
50 4
Golang语言goroutine协程篇
|
1月前
|
安全 Java Go
【Golang入门】简介与基本语法学习
Golang语言入门教程,介绍了Go语言的简介、基本语法、程序结构、变量和常量、控制结构、函数、并发编程、接口和类型、导入包、作用域以及错误处理等关键概念,为初学者提供了一个全面的学习起点。
23 0
|
3月前
|
机器学习/深度学习 存储 人工智能
Golang bytes 包学习
Golang bytes 包学习
24 3
|
3月前
|
NoSQL Unix 编译器
Golang协程goroutine的调度与状态变迁分析
文章深入分析了Golang中goroutine的调度和状态变迁,包括Grunnable、Gwaiting、Grunning和Gsyscall等状态,以及它们之间的转换条件和原理,帮助理解Go调度器的内部机制。
44 0
|
4月前
|
编译器 Go C语言
通过例子学习在golang中调试程序
【7月更文挑战第4天】Go语言支持使用cgo进行汇编调试,官方文档在golang.org/doc/asm。注意,调试Go运行时可能遇到变量不可用或行号错误,需谨慎使用step命令。
72 1
通过例子学习在golang中调试程序