Go语言通过goroutine和channel实现高效并发,使用go关键字启动goroutine;2. 主goroutine不等待其他goroutine,需用sync.WaitGroup同步,通过Add、Done、Wait方法确保所有任务完成。

Go语言的并发模型基于goroutine和channel,使得编写高并发程序变得简单高效。goroutine是Go运行时调度的轻量级线程,启动成本低,一个Go程序可以轻松启动成千上万个goroutine。
如何启动一个goroutine
在函数或方法调用前加上go关键字,即可让该函数在新的goroutine中执行。
示例:go func() {
fmt.Println("Hello from goroutine")
}()
主goroutine(main函数)不会等待其他goroutine结束。如果主程序退出,所有未完成的goroutine都会被强制终止。
使用WaitGroup同步多个goroutine
当需要等待一组goroutine完成时,可使用sync.WaitGroup进行同步。
立即学习“go语言免费学习笔记(深入)”;
常用方法:- Add(n):增加计数器
- Done():计数器减1
- Wait():阻塞直到计数器为0
示例代码:
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Goroutine %d done\n", id)
}(i)
}
wg.Wait() // 等待所有goroutine完成
通过channel进行goroutine间通信
channel是goroutine之间传递数据的安全方式,避免了共享内存带来的竞态问题。
创建channel:ch := make(chan string)
向channel发送数据:ch
从channel接收数据:value :=
云模块_YunMOK网站管理系统采用PHP+MYSQL为编程语言,搭载自主研发的模块化引擎驱动技术,实现可视化拖拽无技术创建并管理网站!如你所想,无限可能,支持创建任何网站:企业、商城、O2O、门户、论坛、人才等一块儿搞定!永久免费授权,包括商业用途; 默认内置三套免费模板。PC网站+手机网站+适配微信+文章管理+产品管理+SEO优化+组件扩展+NEW Login界面.....目测已经遥遥领先..
带缓冲的channel:
ch := make(chan int, 5) // 缓冲大小为5
缓冲channel非阻塞发送,直到缓冲区满为止。
实际应用示例:生产者-消费者模型
func producer(ch chan<- int) {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(time.Millisecond * 100)
}
close(ch)
}
func consumer(ch <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for value := range ch {
fmt.Println("Received:", value)
}
}
主函数中启动生产者和消费者:
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go producer(ch)
go consumer(ch, &wg)
wg.Wait()
避免常见并发问题
goroutine虽然方便,但也容易引发以下问题:
- 竞态条件:多个goroutine同时访问共享变量。可通过互斥锁(sync.Mutex)或channel避免。
- 死锁:goroutine相互等待导致程序挂起。确保channel的发送和接收配对,及时关闭不再使用的channel。
- 资源泄漏:goroutine一直阻塞未退出。使用context包控制超时或取消。
使用context控制goroutine生命周期:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
go func() {
select {
case <-time.After(3 * time.Second):
fmt.Println("Work done")
case <-ctx.Done():
fmt.Println("Cancelled due to timeout")
}
}()
<-ctx.Done() // 等待上下文结束
基本上就这些。掌握goroutine、channel、WaitGroup和context的组合使用,就能写出稳定高效的并发程序。关键是理解“不要通过共享内存来通信,而应该通过通信来共享内存”这一Go并发哲学。










