理解Go语言中的通道

Go语言使用通道(Channel)作为Goroutine之间的通信方式,避免了共享内存带来的复杂性。通道可以实现数据的同步和非阻塞通信。本文介绍了通道的基本使用,包括创建无缓冲和有缓冲的通道、阻塞和流程控制、通道作为函数参数、使用`select`语句以及退出通道的方法。
摘要由CSDN通过智能技术生成

1.使用通道

        如果说Goroutine是一种支持并发编程的方式,那么通道就是一种与Goroutine通信的方式。通道让数据能够进入和离开Goroutine,可方便Goroutine之间进行通信。

“不要通过共享内存来通信,而通过通信来共享内存。”

        这句话说明了Go语言并发实现方式的不同之处,这部分有必要做进一步解释。在其他编程语言中,并发编程通常是通过在多个进程或线程之间共享内存实现的。共享内存能够让程序同步,确保程序以合乎逻辑的方式执行。在程序执行过程中,进程或线程可能对共享内存加锁,以禁止其他进程或线程修改它。这合乎情理,因为如果在操作期间共享内存被其他进程修改,可能会带来灾难性后果--引发Bug或导致程序崩溃。通过这种方式给内存加锁,可确保它是独占的--只有一个进程或线程能够访问它。

         这听起来可能太过抽象,我们来看一个例子:两个人持有一个联名帐户,他们同时要从这个帐户支付费用,但这两笔交易的总额超过了帐户余额。如果两个交易同时进行且不加锁,则余额检查可能表明资金充足,但实际上资金不够;然而,如果第一个交易将帐户加锁,则直到交易完成,都可避免这样的情况发生。对于简单的并发而言,这种方式看似合理,但如果联名帐户有20个持有人,且他们经常使用这个帐户进行交易呢?在这种情况下,加锁管理工作或能非常复杂。

        共享内存和锁的管理工作并非那么容易,很多编程语言要求程序员对内存和内存管理有深入认识。即便是久经沙场的程序员也会遇到这样的情形,即为找出进程或线程争用共享内存而引发的Bug,需要花费数天时间。在使用共享内存的并发环境中,如果不能始终知道程序的哪部分将先更新数据,那么将难以推断其中发生的情况。

        虽然使用共享内存有其用武之地,但Go语言使用通道在Goroutine之间收发消息,避免了使用共享内存。严格地说,Goroutine并不是线程,但您可将其视为线程,因为它们能够以非阻塞方式执行代码。在前面关于两人持有一个联合帐户的例子中,如果使用Goroutine,将可能向通道发送一条消息,而通道可能限制后续交易或另一个帐户持有人的行为。通过收发消息,使得能够以推送方式协调并发事件。事件发生时,可将触发的消息推送给接收者。使作共享内存时,程序必须检查共享内存。在变化频繁的并发编程环境中,很多人都认为使用消息是一种更佳的通信方式。

        下列程序使用了Goroutine来执行运行速度缓慢的函数,以免阻塞整个程序的执行。

package main

import (
	"fmt"
	"time"
)

func slowFunc() {
	time.Sleep(time.Second * 2)
	fmt.Println("sleeper() finished")
}

func main() {
	go slowFunc()
	fmt.Println("I am not shown until slowFunc( ) completes")
	time.Sleep(time.Second * 3)
}

        在程序中,使用了一个定时器,旨在避免程序在 Goroutine 返回前退出。在介绍Goroutine的示例中,这样做完全可行,但在更复杂的并发程序中,使用定时器绝非好主意。为了管理 Goroutine 和并发,GO 语言提供了通道。在上面的程序中,如果能够在 Goroutine 和程序之间通信,并让 Goroutine 结束时能够告诉主程序就好了.这正是通道的用武之地.

        通道的创建语法如下:

c := make(chan string)

语法解读如下:

  • 使用简短变量赋值,将变量 c 初始化为 := 右边的值
  • 使用内置函数 make 创建一个通道,这里使用关键字 chan 指定的
  • 关键字 chan 后面的 string 指出这个通道将用于存储字符串数据,这意味着这个通道只能用于收发字符串值

向通道发送消息的语法如下:

c <- "Hello World"

请注意其中的 <- ,这表示将右边的字符串发送给左边的通道.如果通道被指定为收发字符串,则只能向它发送字符串消息,如果向它发送其他类型的消息将导致错误. 

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mindfulness code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值