首页  >  文章  >  后端开发  >  Golang函数并发编程中通道的类型和规则

Golang函数并发编程中通道的类型和规则

王林
王林原创
2024-04-18 08:57:02323浏览

通道是 Go 语言中用于在并发函数间安全传递数据的通信机制,提供的数据竞争保护避免直接访问共享内存。通道类型包括无缓冲通道(chan T)和缓冲通道(chan T, int)。规则包括发送值(

Golang函数并发编程中通道的类型和规则

Go 语言函数并发编程中的通道类型和规则

通道是 Go 语言中用于在并发函数之间安全地传递数据的通信机制。它们提供了一个抽象层,使函数无需直接访问共享内存,从而避免了数据竞争。

通道类型

  • 无缓冲通道 (chan T):此类通道没有内部缓冲区,因此发送方和接收方必须同时处于就绪状态才能进行通信。
  • 缓冲通道 (chan T, int):此类通道有一个指定大小的内部缓冲区,用于存储值。它允许发送方在接收方未准备好接收时发送值,反之亦然。

通道规则

  • 发送值:使用 send 操作符 () 将值发送到通道。必须先使用 <code> 锁定通道,然后再发送值。
  • 接收值:使用 receive 操作符 (->) 从通道接收值。与发送值类似,必须先使用 chan 锁定通道,然后再接收值。
  • 关闭通道:使用 close(chan) 关闭通道。关闭后,无法再向通道发送值,但可以继续接收已发送的值。
  • 通道容量:缓冲通道有一个指定的最大容量,由创建时指定的第二个参数确定。如果通道已满,发送方将阻塞,直到有空间可用。
  • 选择:select 语句允许从多个通道进行选择性接收或发送。它提供了事件驱动的并发编程模型。

实战案例

考虑一个计算素数的程序:

package main

import (
    "fmt"
    "math"
    "sync"
    "time"
)

// 工作单元
type WorkUnit struct {
    n        uint64
    isPrime  bool
    finished chan bool
}

// 素数计算函数
func isPrime(n uint64) bool {
    if n <= 1 {
        return false
    }
    for i := uint64(2); i <= uint64(math.Sqrt(float64(n))); i++ {
        if n%i == 0 {
            return false
        }
    }
    return true
}

// 工作器函数
func worker(in, out chan *WorkUnit, wg *sync.WaitGroup) {
    defer wg.Done()
    for unit := range in {
        unit.isPrime = isPrime(unit.n)
        close(unit.finished)
        out <- unit
    }
}

func main() {
    // 输入通道
    in := make(chan *WorkUnit)
    // 输出通道
    out := make(chan *WorkUnit)

    // 初始化工作单元
    units := make([]*WorkUnit, 500000)
    for i := range units {
        units[i] = &WorkUnit{
            n:        uint64(i),
            finished: make(chan bool),
        }
    }

    // 启动工作器
    wg := &sync.WaitGroup{}
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go worker(in, out, wg)
    }

    // 将工作单元推送到输入通道
    start := time.Now()
    for _, unit := range units {
        in <- unit
    }
    close(in)

    // 从输出通道接收结果
    for unit := range out {
        <-unit.finished
    }
    elapsed := time.Since(start)

    fmt.Printf("Took %s\n", elapsed)
}

在这个示例中:

  • in 通道是无缓冲通道,用于将工作单元发送到工作器函数。
  • out 通道是缓冲通道,用于将计算结果传回主函数。
  • finished 通道是一个无缓冲通道,用于在工作器函数完成计算后向主函数发出信号。

该程序演示了如何在 Go 中使用通道来实现并发计算,有效地利用了多个 CPU 核心。

以上是Golang函数并发编程中通道的类型和规则的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn