温馨提示×

Linux下Go语言的并发编程实践

小樊
33
2026-05-01 08:57:32
栏目: 编程语言

在Linux下使用Go语言进行并发编程是一种非常高效的方式,因为Go语言从设计之初就内置了对并发的支持。以下是一些在Linux下使用Go语言进行并发编程的实践:

1. Goroutines

Goroutines是Go语言中实现并发的基本单位。它们比传统的线程更轻量级,可以轻松创建成千上万个。

package main

import (
    "fmt"
    "time"
)

func printNumbers() {
    for i := 1; i <= 5; i++ {
        fmt.Printf("Number: %d\n", i)
        time.Sleep(1 * time.Second)
    }
}

func main() {
    go printNumbers() // 启动一个新的goroutine
    time.Sleep(6 * time.Second) // 等待足够的时间让goroutine完成
}

2. Channels

Channels是Go语言中用于在goroutines之间进行通信和同步的原语。它们可以用来传递数据,确保数据的一致性和同步。

package main

import (
    "fmt"
)

func sum(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
    c <- sum // 将结果发送到channel
    close(c) // 关闭channel
}

func main() {
    s := []int{7, 2, 8, -9, 4, 0}
    c := make(chan int)
    go sum(s[:len(s)/2], c) // 启动一个新的goroutine来计算前半部分的和
    go sum(s[len(s)/2:], c) // 启动另一个goroutine来计算后半部分的和

    x, y := <-c, <-c // 从channel接收结果
    fmt.Println(x, y, x+y)
}

3. Select语句

Select语句用于在多个channel操作中进行选择。它可以用来等待多个通信操作中的一个完成。

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()

    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("Received", msg1)
        case msg2 := <-c2:
            fmt.Println("Received", msg2)
        }
    }
}

4. Sync包

Go语言的sync包提供了许多用于同步的工具,如WaitGroupMutexCond等。

WaitGroup

WaitGroup用于等待一组goroutines完成。

package main

import (
    "fmt"
    "sync"
)

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("Worker %d starting\n", id)
    // 模拟工作
    fmt.Printf("Worker %d done\n", id)
}

func main() {
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }

    wg.Wait()
    fmt.Println("All workers done")
}

Mutex

Mutex用于保护共享资源,防止多个goroutines同时访问。

package main

import (
    "fmt"
    "sync"
)

var (
    counter int
    mutex   sync.Mutex
)

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

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            increment()
        }()
    }

    wg.Wait()
    fmt.Println("Counter:", counter)
}

5. Context包

Context包用于在goroutines之间传递截止时间、取消信号和其他请求范围的值。

package main

import (
    "context"
    "fmt"
    "time"
)

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("Worker stopping")
            return
        default:
            fmt.Println("Worker working")
            time.Sleep(500 * time.Millisecond)
        }
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    go worker(ctx)
    <-ctx.Done()
    fmt.Println("Main function done")
}

通过这些实践,你可以在Linux下高效地使用Go语言进行并发编程。记住,合理使用goroutines、channels和同步工具可以显著提高程序的性能和可靠性。

0