Golang 함수 동시 프로그래밍의 채널 유형 및 규칙

王林
풀어 주다: 2024-04-18 08:57:02
원래의
344명이 탐색했습니다.

채널은 동시 기능 간에 데이터를 안전하게 전송하기 위한 Go 언어의 통신 메커니즘으로, 공유 메모리에 직접 액세스하지 않도록 데이터 경합 보호 기능을 제공합니다. 채널 유형에는 버퍼링되지 않은 채널(chan T)과 버퍼링된 채널(chan T, int)이 포함됩니다. 규칙에는 값 전송(

Golang 함수 동시 프로그래밍의 채널 유형 및 규칙

Go 언어 기능 동시 프로그래밍의 채널 유형 및 규칙

채널은 동시 기능 간에 데이터를 안전하게 전송하기 위한 Go 언어의 통신 메커니즘입니다. 함수가 공유 메모리에 직접 액세스할 필요가 없도록 추상화 계층을 제공하여 데이터 경합을 방지합니다.

채널 유형

  • 버퍼링되지 않은 채널(chan T): 이 유형의 채널에는 내부 버퍼가 없으므로 송신자와 수신자가 동시에 통신할 준비가 되어 있어야 합니다.
  • 버퍼 채널(chan T, int): 이 유형의 채널에는 값을 저장하기 위해 지정된 크기의 내부 버퍼가 있습니다. 이를 통해 수신자가 값을 받을 준비가 되지 않았을 때 발신자가 값을 보낼 수 있으며 그 반대의 경우도 마찬가지입니다.

채널 규칙

  • 값 보내기: 채널에 값을 보내려면 send 연산자()를 사용하세요. 값을 전송하기 전에 <code>을 사용하여 채널을 잠가야 합니다. <code>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
값 수신:

채널에서 값을 받으려면 receive 연산자(->)를 사용하세요. 값을 보내는 것과 마찬가지로 값을 받기 전에 chan를 사용하여 채널을 잠가야 합니다.

🎜🎜채널 폐쇄: 🎜채널을 폐쇄하려면 close(chan)를 사용하세요. 종료 후에는 해당 채널에 더 이상 값을 보낼 수 없지만, 이미 보낸 값은 계속해서 받을 수 있습니다. 🎜🎜🎜채널 용량: 🎜버퍼 채널에는 생성 시 지정된 두 번째 매개변수에 따라 결정되는 지정된 최대 용량이 있습니다. 채널이 꽉 차면 공간이 확보될 때까지 발신자는 차단됩니다. 🎜🎜🎜Select: 🎜select 문을 사용하면 여러 채널에서 선택적으로 수신하거나 보낼 수 있습니다. 이벤트 기반 동시 프로그래밍 모델을 제공합니다. 🎜🎜🎜🎜실용적 예🎜🎜🎜소수를 계산하는 프로그램을 생각해 보세요: 🎜rrreee🎜이 예에서: 🎜🎜🎜in 채널은 작업 단위를 작업자 함수로 보내는 데 사용되는 버퍼링되지 않은 채널입니다. 🎜🎜out 채널은 계산 결과를 다시 주 함수로 전송하는 데 사용되는 버퍼 채널입니다. 🎜🎜 finished 채널은 작업자 함수가 계산을 완료한 후 주 함수에 신호를 보내는 데 사용되는 버퍼링되지 않은 채널입니다. 🎜🎜🎜이 프로그램은 채널을 사용하여 Go에서 동시 계산을 구현하고 여러 CPU 코어를 효과적으로 활용하는 방법을 보여줍니다. 🎜

위 내용은 Golang 함수 동시 프로그래밍의 채널 유형 및 규칙의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿