网站首页 > 技术文章 正文
在 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 中接收结果。
- 上一篇: C++防御性编程,提高代码的健壮性
- 下一篇: 聊聊并发编程: Lock
猜你喜欢
- 2025-05-15 穿透与击穿:缓存世界的两场“攻击”,Java工程师如何见招拆招?
- 2025-05-15 一篇文章快速搞懂C++线程同步机制
- 2025-05-15 C语言编写多线程,什么时候要使用互斥锁?为什么要使用互斥锁?
- 2025-05-15 go语言并发原语RWMutex实现原理及闭坑指南
- 2025-05-15 实战经验:一次错误使用 go-cache 包导致出现的线上问题
- 2025-05-15 3. 复合数据类型
- 2025-05-15 Linux ALSA 音频系统:物理链路篇02
- 2025-05-15 聊聊并发编程: Lock
- 2025-05-15 C++防御性编程,提高代码的健壮性
- 2025-05-15 Linux C++实现多线程同步的四种方式(超级详细)
- 06-22Python开发工程师必会的3个设计模式(工厂、单例、适配器)
- 06-22创建型设计模式——工厂模式和抽象工厂模式
- 06-221. 工厂模式详解
- 06-22工厂模式详解
- 06-22设计模式问题:说一说简单工厂模式?
- 06-22深入设计模式:工厂方法
- 06-22C++设计模式——简单工厂模式
- 06-22什么是工厂模式?工厂模式有哪些类型?如何使用它们?
- 最近发表
- 标签列表
-
- axure 注册码 (25)
- exploit db (21)
- mutex_lock (30)
- oracleclient (27)
- think in java (14)
- javascript权威指南 (19)
- nfs (25)
- componentart (17)
- yii框架 (14)
- springbatch (28)
- oracle数据库备份 (25)
- iptables (21)
- 自动化单元测试 (18)
- mvc模式 (13)
- python编写软件 (14)
- dir (26)
- connectionstring属性尚未初始化 (23)
- output (32)
- panel滚动条 (28)
- centos 5 4 (23)
- sql学习 (33)
- dfn (14)
- http error 503 (21)
- pop3服务器 (18)
- 图表组件 (17)