插件窝 干货文章 Linux平台上Golang如何进行并发控制

Linux平台上Golang如何进行并发控制

并发 Goroutine 控制 Go 941    来源:    2025-05-10

Golang 在 Linux 平台上的并发控制

Go 语言以其出色的并发模型而闻名,在 Linux 平台上提供了多种并发控制机制。以下是主要的并发控制方法:

1. Goroutine 基础

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

go func() {
    // 并发执行的代码
}()

2. Channel 同步

Channel 是 Go 的核心并发原语,用于 Goroutine 间通信:

ch := make(chan int)

// 发送数据
go func() {
    ch <- 42
}()

// 接收数据
value := <-ch

3. WaitGroup 等待组

sync.WaitGroup 用于等待一组 Goroutine 完成:

var wg sync.WaitGroup

for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(i int) {
        defer wg.Done()
        fmt.Println(i)
    }(i)
}

wg.Wait() // 等待所有 Goroutine 完成

4. Mutex 互斥锁

sync.Mutex 用于保护共享资源:

var (
    counter int
    mu      sync.Mutex
)

func increment() {
    mu.Lock()
    defer mu.Unlock()
    counter++
}

5. RWMutex 读写锁

sync.RWMutex 提供更高效的读写控制:

var (
    data  map[string]string
    rwMux sync.RWMutex
)

// 读操作
func read(key string) string {
    rwMux.RLock()
    defer rwMux.RUnlock()
    return data[key]
}

// 写操作
func write(key, value string) {
    rwMux.Lock()
    defer rwMux.Unlock()
    data[key] = value
}

6. Once 单次执行

sync.Once 确保某操作只执行一次:

var once sync.Once

func setup() {
    once.Do(func() {
        // 只执行一次的初始化代码
    })
}

7. Context 上下文控制

context 包用于控制 Goroutine 的生命周期:

ctx, cancel := context.WithCancel(context.Background())

go func(ctx context.Context) {
    select {
    case <-ctx.Done():
        return // 被取消
    case <-time.After(time.Second):
        fmt.Println("工作完成")
    }
}(ctx)

// 取消操作
cancel()

8. Select 多路复用

select 语句用于监听多个 Channel:

select {
case msg1 := <-ch1:
    fmt.Println(msg1)
case msg2 := <-ch2:
    fmt.Println(msg2)
case <-time.After(time.Second):
    fmt.Println("超时")
}

9. 原子操作

sync/atomic 包提供原子操作:

var count int32

atomic.AddInt32(&count, 1) // 原子增加

10. Worker Pool 模式

使用缓冲 Channel 实现工作池:

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Println("worker", id, "processing job", j)
        results <- j * 2
    }
}

jobs := make(chan int, 100)
results := make(chan int, 100)

// 启动 3 个 worker
for w := 1; w <= 3; w++ {
    go worker(w, jobs, results)
}

// 发送 9 个任务
for j := 1; j <= 9; j++ {
    jobs <- j
}
close(jobs)

// 收集结果
for a := 1; a <= 9; a++ {
    <-results
}

性能考虑

  1. 在 Linux 上,Goroutine 调度器会利用多核 CPU
  2. 避免过度使用锁,优先考虑 Channel
  3. 使用 runtime.GOMAXPROCS() 控制使用的 CPU 核心数

调试工具

  1. go tool trace - 可视化并发执行
  2. pprof - 性能分析
  3. -race 标志 - 检测数据竞争

Go 的并发模型在 Linux 平台上表现优异,合理使用这些并发控制机制可以构建高效可靠的并发程序。