第一章 为什么你的代码像堵车?——并发的魅力
想象一下,你走进一家咖啡店,如果店员每次只服务一位顾客,等前面的人纠结完要喝什么、付钱、找零,才轮到下一位,你估计早就掉头走人了。现实生活中,我们天生就懂得“并发”——咖啡师在做咖啡的同时,收银员在收款,糕点师在准备甜点。
可是,当我们写代码时,却常常不自觉地陷入了“单线程思维”:程序一步一步执行,下载文件时用户界面卡死,处理数据时无法响应用户点击...
我曾经写过一个数据处理的脚本,它需要从10个网站抓取信息,结果我的代码乖乖地一个接一个访问,花了整整2分钟。后来我用Go的并发改造后,10个任务同时进行,12秒就完成了!这种效率提升不是一点点,而是数量级的差距。
Go语言的并发哲学很直接:既然现代计算机都是多核的,为什么不让它们同时工作呢?就像一支高效的团队,每个人各司其职,而不是所有事情都让一个人干。
第二章 Go语言的“影分身之术”——goroutine入门
在Java或C++中,创建线程是个重量级操作,每个线程都要消耗不少内存(通常以MB计),创建和销毁也有不小开销。但Go的goroutine则轻量得多——初始栈大小只有2KB,创建比线程快十倍以上。
goroutine是什么? 你可以把它理解为Go的“影分身之术”。在《火影忍者》中,鸣人可以变出成百上千个分身同时执行不同任务。goroutine也是如此。
看看这个简单的例子:
package main
import (
"fmt"
"time"
)
func sayHello() {
for i := 0; i < 3; i++ {
fmt.Printf("你好,我是goroutine!\n")
time.Sleep(time.Millisecond * 100)
}
}
func main() {
// 启动一个goroutine
go sayHello()
// 主线程也同时工作
for i := 0; i < 3; i++ {
fmt.Printf("你好,我是主线程!\n")
time.Sleep(time.Millisecond * 100)
}
// 等待一下让goroutine有机会执行
time.Sleep(time.Second)
}
运行这个程序,你会看到输出是交错出现的,说明两个函数在同时执行。关键是那个神奇的go关键字——它就像启动影分身的咒语,在普通函数调用前加上go,就把这个函数变成了并发执行的goroutine。
第三章 多个goroutine如何不打架?——channel来帮忙
多个goroutine同时运行很酷,但如果它们需要协作,就会遇到问题。想象一下厨房里有多个厨师在做同一道菜,如果他们不协调,很可能出现重复放盐或者漏掉某个步骤的情况。
这就是Go语言设计channel的初衷——让goroutine之间可以安全地通信。
channel就像goroutine之间的传送带:一个goroutine把数据放在传送带一端,另一个goroutin

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



