尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Go09-并发编程

Go09-并发编程
📅 发布时间:2026/7/16 21:31:21

第8章:并发编程

8.1 并发基础

Go 使用 goroutine 和 channel 实现并发,这是 Go 最强大的特性之一。

Goroutine

Goroutine 是轻量级线程,由 Go 运行时管理:

packagemainimport("fmt""time")funcsayHello(namestring){fori:=0;i<5;i++{fmt.Printf("Hello, %s! (%d)\n",name,i)time.Sleep(100*time.Millisecond)}}funcmain(){// 启动 goroutinegosayHello("张三")gosayHello("李四")// 主 goroutine 等待time.Sleep(1*time.Second)fmt.Println("主程序结束")}

启动多个 Goroutine

funcmain(){// 启动多个 goroutinefori:=0;i<10;i++{gofunc(nint){fmt.Printf("goroutine %d\n",n)}(i)// 注意:传递参数避免闭包问题}time.Sleep(time.Second)}

8.2 Channel

Channel 是 goroutine 之间通信的管道。

基本 Channel

// 创建 channelch:=make(chanint)// 发送数据gofunc(){ch<-42// 发送}()// 接收数据value:=<-ch// 接收fmt.Println(value)// 42// 关闭 channelclose(ch)

带缓冲的 Channel

// 无缓冲 channel(同步)ch1:=make(chanint)// 带缓冲 channel(异步)ch2:=make(chanint,10)// 缓冲区大小为 10// 发送数据(不阻塞,直到缓冲区满)ch2<-1ch2<-2// 接收数据fmt.Println(<-ch2)// 1fmt.Println(<-ch2)// 2

Channel 方向

// 只发送 channelfuncproducer(chchan<-int){fori:=0;i<10;i++{ch<-i}close(ch)}// 只接收 channelfuncconsumer(ch<-chanint){forv:=rangech{fmt.Println(v)}}funcmain(){ch:=make(chanint)goproducer(ch)consumer(ch)}

8.3 Channel 操作

Select 语句

// 同时监听多个 channelfuncmain(){ch1:=make(chanstring)ch2:=make(chanstring)gofunc(){time.Sleep(1*time.Second)ch1<-"来自 channel 1"}()gofunc(){time.Sleep(2*time.Second)ch2<-"来自 channel 2"}()// select 等待第一个完成的 channelselect{casemsg:=<-ch1:fmt.Println(msg)casemsg:=<-ch2:fmt.Println(msg)case<-time.After(3*time.Second):fmt.Println("超时")}}

超时控制

funcfetchData()(string,error){ch:=make(chanstring,1)gofunc(){// 模拟耗时操作time.Sleep(2*time.Second)ch<-"数据"}()select{caseresult:=<-ch:returnresult,nilcase<-time.After(1*time.Second):return"",errors.New("请求超时")}}

非阻塞操作

select{casemsg:=<-ch:fmt.Println("收到消息:",msg)default:fmt.Println("没有消息")}

8.4 同步原语

sync.WaitGroup

packagemainimport("fmt""sync")funcmain(){varwg sync.WaitGroupfori:=0;i<10;i++{wg.Add(1)// 增加计数器gofunc(nint){deferwg.Done()// 减少计数器fmt.Printf("goroutine %d\n",n)}(i)}wg.Wait()// 等待所有 goroutine 完成fmt.Println("所有 goroutine 完成")}

sync.Mutex

packagemainimport("fmt""sync")typeCounterstruct{mu sync.Mutex valueint}func(c*Counter)Increment(){c.mu.Lock()// 加锁deferc.mu.Unlock()// 解锁c.value++}func(c*Counter)Value()int{c.mu.Lock()deferc.mu.Unlock()returnc.value}funcmain(){counter:=&Counter{}varwg sync.WaitGroupfori:=0;i<1000;i++{wg.Add(1)gofunc(){deferwg.Done()counter.Increment()}()}wg.Wait()fmt.Println("最终值:",counter.Value())// 1000}

sync.RWMutex(读写锁)

typeCachestruct{mu sync.RWMutex itemsmap[string]string}func(c*Cache)Get(keystring)(string,bool){c.mu.RLock()// 读锁deferc.mu.RUnlock()value,ok:=c.items[key]returnvalue,ok}func(c*Cache)Set(key,valuestring){c.mu.Lock()// 写锁deferc.mu.Unlock()c.items[key]=value}

sync.Once

typeSingletonstruct{instanceinterface{}once sync.Once}func(s*Singleton)Get()interface{}{s.once.Do(func(){s.instance=createInstance()})returns.instance}

sync.Map

packagemainimport("fmt""sync")funcmain(){varm sync.Map// 存储m.Store("key1","value1")m.Store("key2","value2")// 读取ifvalue,ok:=m.Load("key1");ok{fmt.Println(value)}// 遍历m.Range(func(key,valueinterface{})bool{fmt.Printf("%v: %v\n",key,value)returntrue// 返回 false 停止遍历})}

8.5 并发模式

Worker Pool

funcworker(idint,jobs<-chanint,resultschan<-int){forjob:=rangejobs{fmt.Printf("worker %d 处理 job %d\n",id,job)time.Sleep(time.Second)results<-job*2}}funcmain(){jobs:=make(chanint,100)results:=make(chanint,100)// 启动 workersforw:=1;w<=3;w++{goworker(w,jobs,results)}// 发送 jobsforj:=1;j<=9;j++{jobs<-j}close(jobs)// 收集结果fora:=1;a<=9;a++{fmt.Println("结果:",<-results)}}

Fan-out / Fan-in

// Fan-out: 多个 worker 读取同一个 channel// Fan-in: 多个 worker 写入同一个 channelfuncfanOut(input<-chanint,workersint)[]<-chanint{channels:=make([]<-chanint,workers)fori:=0;i<workers;i++{channels[i]=process(input)}returnchannels}funcfanIn(channels...<-chanint)<-chanint{varwg sync.WaitGroup merged:=make(chanint)for_,ch:=rangechannels{wg.Add(1)gofunc(c<-chanint){deferwg.Done()forv:=rangec{merged<-v}}(ch)}gofunc(){wg.Wait()close(merged)}()returnmerged}

Pipeline

funcgenerate(nums...int)<-chanint{out:=make(chanint)gofunc(){for_,n:=rangenums{out<-n}close(out)}()returnout}funcsquare(in<-chanint)<-chanint{out:=make(chanint)gofunc(){forn:=rangein{out<-n*n}close(out)}()returnout}funcmain(){// Pipeline: generate -> squareforv:=rangesquare(generate(1,2,3,4,5)){fmt.Println(v)// 1, 4, 9, 16, 25}}

8.6 练习

  1. 实现一个简单的并发爬虫
  2. 使用 Worker Pool 模式处理批量任务
  3. 实现一个并发安全的缓存
  4. 编写一个 Pipeline 处理数据流

8.7 下一章

下一章我们将学习 Go 语言的标准库精讲。

相关新闻

  • 2026化工行业 GHS/CLP 国产标签打印软件合规打印方案
  • Linux服务器双向SSH免密登录配置与安全实践指南
  • 2026快速建团队,美国员工外包服务商推荐 - 2027品牌AI展

最新新闻

  • 【单片机毕业设计】 基于 STM32 的指纹考勤与蓝牙 APP 管理系统设计与实现 ,基于 STM32 单片机的智能指纹考勤终端设计及移动端开发(015002)
  • AltoClef社区贡献指南:如何为开源Minecraft机器人项目做贡献
  • gvt常见问题解决:10个典型使用场景与解决方案
  • 大数据-Hadoop-统一操作界面:HUE(Hadoop User Experience)【一站式Web平台,整合HDFS、Hive、YARN等核心组件操作】
  • 2026年广饶股权变更代办避坑指南:企业转让、涉税优化、风险防控全攻略 - 资讯在线
  • Operator 的台账:概念、设计与实践

日新闻

  • Toon Boom Harmony 高效工作流:从节点视图到镜头标记的实战技巧
  • 真力时售后维修电话,为您提供专业腕表保养与故障修复服务权威公示(2026年7月最新) - 亨得利官方服务中心
  • 【C++】类和对象--构造函数进阶(初始化列表与explicit)

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号