网站首页 > 教程文章 正文
在 Go 语言里,并行和并发是两个不同但紧密相关的概念。并发是指程序能够处理多个任务,而并行是指多个任务同时执行。Go 语言凭借 goroutine 和 channel 为并发和并行编程提供了强大的支持,下面为你详细介绍其实现方法。
并发编程
Go 语言使用 goroutine 实现并发,goroutine 是一种轻量级的线程,由 Go 运行时管理,创建和销毁的开销很小,能轻松创建成千上万个 goroutine。
示例代码
golang-concurrency-exampleGo 语言并发编程示例
package main
import (
"fmt"
"time"
)
// 模拟一个耗时任务
func task(id int) {
fmt.Printf("Task %d started\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("Task %d finished\n", id)
}
func main() {
// 启动多个 goroutine
for i := 1; i <= 3; i++ {
go task(i)
}
// 让主 goroutine 等待一段时间,确保其他 goroutine 有机会执行
time.Sleep(3 * time.Second)
fmt.Println("Main goroutine exiting")
}
代码解释
- go task(i):这行代码启动了一个新的 goroutine 来执行 task 函数。
- time.Sleep(3 * time.Second):在主 goroutine 中使用 Sleep 函数等待一段时间,以确保其他 goroutine 有机会执行。
并行编程
并行编程通常借助多个 goroutine 同时运行来实现,并且可以利用多核处理器。Go 语言的运行时会自动将 goroutine 分配到不同的线程上执行。
示例代码
golang-parallelism-exampleGo 语言并行编程示例
package main
import (
"fmt"
"sync"
"time"
)
// 模拟一个耗时任务
func task(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("Task %d started\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("Task %d finished\n", id)
}
func main() {
var wg sync.WaitGroup
// 启动多个 goroutine
for i := 1; i <= 3; i++ {
wg.Add(1)
go task(i, &wg)
}
// 等待所有 goroutine 完成
wg.Wait()
fmt.Println("All tasks finished")
}
代码解释
- sync.WaitGroup:用于等待一组 goroutine 完成。wg.Add(1) 表示增加一个等待的 goroutine,defer wg.Done() 表示该 goroutine 完成,wg.Wait() 会阻塞主 goroutine,直到所有等待的 goroutine 都完成。
并发同步
在并发编程中,不同的 goroutine 可能会访问共享资源,为了避免数据竞争,需要进行同步操作。Go 语言提供了 sync.Mutex 和 channel 等机制来实现同步。
使用sync.Mutex示例
golang-mutex-exampleGo 语言使用 sync.Mutex 进行并发同步示例
package main
import (
"fmt"
"sync"
)
var (
counter int
mutex sync.Mutex
)
// 增加计数器的值
func increment(wg *sync.WaitGroup) {
defer wg.Done()
mutex.Lock()
counter++
mutex.Unlock()
}
func main() {
var wg sync.WaitGroup
// 启动多个 goroutine 来增加计数器的值
for i := 0; i < 1000; i++ {
wg.Add(1)
go increment(&wg)
}
// 等待所有 goroutine 完成
wg.Wait()
fmt.Println("Counter:", counter)
}
代码解释
- sync.Mutex:用于保护共享资源 counter。mutex.Lock() 会锁定互斥锁,防止其他 goroutine 访问共享资源,mutex.Unlock() 会解锁互斥锁。
使用channel示例
golang-channel-exampleGo 语言使用 channel 进行并发同步示例
package main
import (
"fmt"
)
// 计算平方和
func squareSum(numbers []int, resultChan chan int) {
sum := 0
for _, num := range numbers {
sum += num * num
}
resultChan <- sum
}
func main() {
numbers := []int{1, 2, 3, 4, 5}
resultChan := make(chan int)
// 启动一个 goroutine 来计算平方和
go squareSum(numbers, resultChan)
// 从 channel 接收结果
result := <-resultChan
close(resultChan)
fmt.Println("Square sum:", result)
}
代码解释
- channel:用于在不同的 goroutine 之间传递数据。resultChan <- sum 表示将计算结果发送到 channel 中,result := <-resultChan 表示从 channel 中接收结果。
- 上一篇: 串行和并行
- 下一篇: 什么是串行通信,什么是并行通信?各有什么不同?
猜你喜欢
- 2025-05-30 运动定律:发展与反思并行
- 2025-05-30 夜读 | 爱与规矩并行,才是一个家庭最好的家教
- 2025-05-30 应用程序并行配置不正确或错误的解决方法
- 2025-05-30 爱与规矩并行,才是一个家庭最好的家教
- 2025-05-30 学习卡片 | 万物并育而不相害,道并行而不相悖
- 2025-05-30 血脂、血压 两高并行很危险
- 2025-05-30 性能测试必须掌握的知识点:并发和并行以及CPU的状态和核心参数
- 2025-05-30 精益生产(Lean Production)基础学习笔记——第19讲
- 2025-05-30 AI智算领域基本概念【8】——并行计算(数据并行)
- 2025-05-30 Java并发包(java.util.concurrent)探秘:高效并行编程的艺术
- 最近发表
-
- 【Python】一文学会使用 Pandas 库
- Docsify-3分钟搭建属于自己的技术文档WIKI
- Elasticsearch数据迁移方案(elasticsearch索引迁移)
- Vue、Nuxt服务端渲染、NodeJS全栈项目
- Android Studio下载Gradle超时解决方案
- 一文讲清楚 Markdown+Typora+Pandoc+图床+PicGo
- 用户说 | 手把手体验通义灵码 2.0 AI 程序员如何让我进阶“架构师”?
- 15.7k star,经典与效率兼备的后台管理框架
- Cursor + 12306 MCP,打造AI智能选票系统,超酷的!
- 别再自建仓库了,云效Maven仓库不限容量免费用
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)