ホームページ  >  記事  >  バックエンド開発  >  Golang関数の同時プログラミングにおけるチャネルの種類とルール

Golang関数の同時プログラミングにおけるチャネルの種類とルール

王林
王林オリジナル
2024-04-18 08:57:02346ブラウズ

チャネルは、同時実行機能間でデータを安全に転送するための Go 言語の通信メカニズムであり、共有メモリへの直接アクセスを回避するデータ競合保護を提供します。チャネル タイプには、バッファなしチャネル (chan T) とバッファありチャネル (chan T、int) があります。ルールには、値の送信 (

Golang関数の同時プログラミングにおけるチャネルの種類とルール

Go 言語関数の同時プログラミングにおけるチャネルのタイプとルール

Go 言語では、チャネルは同時関数間で通信するために使用されます。データを安全に配信するための通信メカニズム。これらは、関数が共有メモリに直接アクセスする必要性を排除する抽象化レイヤーを提供し、データ競合を回避します。

チャネル タイプ

  • バッファなしチャネル (チャネル T) : このタイプのチャネルには内部バッファがないため、送信者と受信者は通信するには、双方が同時に準備完了状態でなければなりません。
  • バッファ付きチャネル (chan T, int): このタイプのチャネルには、値を格納するための指定されたサイズの内部バッファがあります。これにより、受信者が値を受信する準備ができていないときに送信者が値を送信したり、その逆が可能になります。

チャネル ルール

  • 値の送信: send 演算子を使用します (&lt ;-) 値をチャネルに送信します。値を送信する前に、 を使用してチャネルをロックする必要があります。
  • 値の受信: receive 演算子 (->) を使用してチャネルから値を受信します。値の送信と同様に、値を受信する前に chan を使用してチャネルをロックする必要があります。
  • チャネルを閉じる: チャネルを閉じるには、close(chan) を使用します。終了後は、チャネルに値を送信できなくなりますが、すでに送信された値は引き続き受信できます。
  • チャネル容量: バッファ チャネルには、作成時に指定された 2 番目のパラメータによって決定される、指定された最大容量があります。チャネルがいっぱいの場合、送信側はスペースが空くまでブロックします。
  • Select: 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 チャネルは、計算結果を main 関数に戻すために使用されるバッファ チャネルです。
  • finished チャネルは、ワーカー関数が計算を完了した後に main 関数に通知するために使用されるバッファリングされていないチャネルです。
このプログラムは、チャネルを使用して Go で同時計算を実装し、複数の CPU コアを効果的に利用する方法を示します。

以上がGolang関数の同時プログラミングにおけるチャネルの種類とルールの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。