golang并发任务教程

发布时间:2024-10-02 19:47:47

Go 语言(Golang)是谷歌发布的一种编程语言,它的并发模型和原生支持的 goroutine 特性使它成为处理高并发的首选语言。在本文中,我们将探讨 Golang 的并发任务教程,帮助您了解如何使用 goroutine、channel 和互斥锁等工具来实现并发编程。

使用 goroutine 实现并发任务

在 Golang 中,goroutine 是一种轻量级的线程,由 Go runtime 负责管理。您可以使用 go 关键字来启动一个新的 goroutine,将函数调用放在 go 后面,就可以快速创建并发任务。

Goroutine 的优势在于它的开销很小,并且可以轻松创建成千上万个 goroutine。以下是一个简单的示例,演示了如何使用 goroutine 来同时执行多个任务:

package main

import (
    "fmt"
    "time"
)

func task(id int) {
    fmt.Println("Task", id, "started")
    time.Sleep(time.Second)
    fmt.Println("Task", id, "done")
}

func main() {
    for i := 1; i <= 10; i++ {
        go task(i)
    }
    time.Sleep(2 * time.Second) // 等待所有 goroutine 完成
}

在上述示例中,我们使用了一个 for 循环来创建 10 个 goroutine,每个 goroutine 都会执行 task 函数。由于每个任务都会休眠一秒钟,我们使用 time.Sleep 函数等待 2 秒钟,以确保所有任务完成。

使用 channel 实现 goroutine 间的通信

在并发编程中,通信是非常重要的,Golang 提供了 channel 来实现 goroutine 之间的通信。channel 是一种安全、高效的数据传输机制,用于在 goroutine 之间发送和接收数据。

以下示例演示了如何使用 channel 在 goroutine 之间传递数据:

package main

import (
    "fmt"
)

func producer(ch chan int) {
    for i := 1; i <= 5; i++ {
        ch <- i // 发送数据到 channel
    }
    close(ch) // 关闭 channel
}

func consumer(ch chan int, done chan bool) {
    for num := range ch { // 从 channel 接收数据
        fmt.Println("Received:", num)
    }
    done <- true // 通知主 goroutine 任务完成
}

func main() {
    ch := make(chan int)
    done := make(chan bool)

    go producer(ch)
    go consumer(ch, done)

    <-done // 等待任务完成
}

在上述示例中,我们创建了两个 goroutine,一个用于生产者,另一个用于消费者。生产者使用 for 循环发送一系列整数到 channel 中,然后关闭 channel。消费者使用 range 循环从 channel 中接收数据,并在接收完所有数据后,通过向 done channel 发送一个布尔值来通知主 goroutine 任务已完成。

使用互斥锁保护共享资源

在并发编程中,当多个 goroutine 同时访问和修改共享资源时,会出现竞态条件(race condition)。为了避免竞态条件,我们可以使用互斥锁(mutex)来保护共享资源。

以下示例展示了如何使用 sync 包中的互斥锁来确保同一时间只有一个 goroutine 可以访问共享资源:

package main

import (
    "fmt"
    "sync"
)

var (
    counter = 0
    mutex   sync.Mutex
    wg      sync.WaitGroup
)

func increment() {
    mutex.Lock() // 加锁
    defer mutex.Unlock() // 解锁 defer
    counter++
    fmt.Println("Counter:", counter)
    wg.Done()
}

func main() {
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go increment()
    }
    wg.Wait()
}

在上述示例中,我们定义了一个全局变量 counter,并创建了一个互斥锁 mutex 和一个等待组 wg。increment 函数通过调用 mutex.Lock() 来加锁,保证每次只有一个 goroutine 能够访问 counter,并在函数结束时使用 defer mutex.Unlock() 来解锁。通过使用互斥锁,我们可以确保 counter 在被并发访问时不会出现问题。

通过本篇文章,您已经了解了如何使用 goroutine、channel 和互斥锁等工具来实现并发编程。这些是 Golang 并发编程的基础知识,希望对您在开发过程中有所帮助。

相关推荐