8.Goroutines和Channels

并发程序可同时处理多个任务,随着硬件发展愈发重要(如 Web 服务器处理海量请求、移动应用多任务并行、批处理隐藏 I/O 延迟),且计算机性能呈非线性增长;Go 语言实现并发有两种核心手段,本章聚焦基于 CSP(顺序通信进程)模型的 goroutine 和 channel,该模型中值在不同 goroutine 间传递(多数情况下仍限制在单一实例),第 9 章则讲解更传统的多线程共享内存并发模型(更贴近主流语言的并发实现),同时深入分析并发程序的风险与陷阱;需注意的是,尽管 Go 对并发的支持是核心优势,但并发程序调试难度高,线性程序的思维易导致错误,首次接触并发的读者需多花时间理解相关示例。

8.1 Goroutines

在Go语言中,每一个并发的执行单元叫作一个goroutine。设想这里的一个程序有两个函数,一个函数做计算,另一个输出结果,假设两个函数没有相互之间的调用关系。一个线性的程序会先调用其中的一个函数,然后再调用另一个。如果程序中包含多个goroutine,对两个函数的调用则可能发生在同一时刻。马上就会看到这样的一个程序。

如果你使用过操作系统或者其它语言提供的线程,那么你可以简单地把goroutine类比作一个线程,这样你就可以写出一些正确的程序了。goroutine和线程的本质区别会在9.8节中讲。

当一个程序启动时,其主函数即在一个单独的goroutine中运行,我们叫它main goroutine。新的goroutine会用go语句来创建。在语法上,go语句是一个普通的函数或方法调用前加上关键字go。go语句会使其语句中的函数在一个新创建的goroutine中运行。而go语句本身会迅速地完成。

8.4 Channels

如果说goroutine是Go语言程序的并发体的话,那么channel就是他们之间的通信机制。一个channels是一个通信机制,它可以让goroutine通过它给另一个发送值信息。

使用内置的make函数可以创建一个channel
ch := make(chan int)

一个channel有发送和接受两个主要操作,都是通信行为。一个发送语句将一个值从一个goroutine通过channel发送到另一个执行接收操作的goroutine。发送和接收两个操作都是用 <‐ 运算符。在发送语句中, <‐ 运算符分割channel和要发送的值。在接收语句中, <‐ 运算符写在channel对象之前。一个不使用接收结果的接收操作也是合法的

image

可以关闭:close(ch)

posted @ 2026-03-23 15:29  cyusouyiku  阅读(14)  评论(0)    收藏  举报