云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

Golang语言如何实现并行和并发

jxf315 2025-05-30 15:28:55 教程文章 4 ℃


在 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 中接收结果。
最近发表
标签列表