ホームページ  >  記事  >  バックエンド開発  >  Golang でのゴルーチンとチャネルの高度な使用法

Golang でのゴルーチンとチャネルの高度な使用法

PHPz
PHPzオリジナル
2023-08-07 12:12:211162ブラウズ

Golang でのゴルーチンとチャネルの高度な使用法

Golang での同時プログラミングでは、ゴルーチンとチャネルは 2 つの非常に重要な概念です。ゴルーチンは同時に実行できる軽量のスレッドであり、チャネルはゴルーチン間の通信メカニズムです。この記事では、Golang でのゴルーチンとチャネルの高度な使用法を探り、コード例で説明します。

1. Goroutine の高度な使用法

  1. Goroutine の多重化は、select ステートメントを通じて実現できます。以下のコード例では、フィボナッチ数列と階乗をそれぞれ計算する 2 つのゴルーチンを作成します。 select ステートメントを使用すると、2 つのゴルーチンが同時に完了するのを待って、計算結果を出力できます。
package main

import (
    "fmt"
)

func fibonacci(n int, c chan<- int) {
    x, y := 0, 1
    for i := 0; i < n; i++ {
        c <- x
        x, y = y, x+y
    }
    close(c)
}

func factorial(n int, c chan<- int) {
    result := 1
    for i := 1; i <= n; i++ {
        result *= i
    }
    c <- result
    close(c)
}

func main() {
    fibChan := make(chan int)
    factChan := make(chan int)

    go fibonacci(10, fibChan)
    go factorial(5, factChan)

    for {
        select {
        case fib, ok := <-fibChan:
            if ok {
                fmt.Println("Fibonacci:", fib)
            } else {
                fibChan = nil
            }

        case fact, ok := <-factChan:
            if ok {
                fmt.Println("Factorial:", fact)
            } else {
                factChan = nil
            }

        default:
            if fibChan == nil && factChan == nil {
                return
            }
        }
    }
}
  1. WaitGroup を通じて Goroutine の完了を待つことができます。 WaitGroup は、Goroutine のグループの完了を待つために使用できるカウンターです。以下のコード例では、フィボナッチ数列と階乗をそれぞれ計算する 2 つのゴルーチンを作成します。 sync.WaitGroup を使用すると、2 つの Goroutine が同時に完了するのを待つことができます。
package main

import (
    "fmt"
    "sync"
)

func fibonacci(n int, c chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    x, y := 0, 1
    for i := 0; i < n; i++ {
        c <- x
        x, y = y, x+y
    }
    close(c)
}

func factorial(n int, c chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    result := 1
    for i := 1; i <= n; i++ {
        result *= i
    }
    c <- result
    close(c)
}

func main() {
    fibChan := make(chan int)
    factChan := make(chan int)
    var wg sync.WaitGroup

    wg.Add(2)

    go fibonacci(10, fibChan, &wg)
    go factorial(5, factChan, &wg)

    go func() {
        wg.Wait()
        close(fibChan)
        close(factChan)
    }()

    for {
        select {
        case fib, ok := <-fibChan:
            if ok {
                fmt.Println("Fibonacci:", fib)
            } else {
                fibChan = nil
            }

        case fact, ok := <-factChan:
            if ok {
                fmt.Println("Factorial:", fact)
            } else {
                factChan = nil
            }

        default:
            if fibChan == nil && factChan == nil {
                return
            }
        }
    }
}

2. チャネルの高度な使用法

  1. バッファ サイズを設定することで、チャネルのブロック動作を制御できます。デフォルトでは、チャネルはバッファリングされていません。つまり、相手の準備が整うまで送受信がブロックされます。 make 関数の 2 番目のパラメータを通じてバッファ サイズを設定できます。次のコード例では、バッファ サイズ 3 のチャネルを作成し、それに 3 つの値を送信します。バッファがいっぱいではないため、送信はブロックされません。
package main

import (
    "fmt"
)

func main() {
    ch := make(chan int, 3)
    ch <- 1
    ch <- 2
    ch <- 3

    fmt.Println(<-ch)
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}
  1. チャネルは、range キーワードを使用して反復できます。 range キーワードを使用して、チャネル内の値を反復することができます。チャネルが閉じられると、反復は自動的に終了します。次のコード例では、カウンター Goroutine を作成し、5 つの値をバッファリングされていないチャネルに送信します。 main 関数では、 range キーワードを使用してチャネル内の値を反復し、出力します。チャンネルが閉じられると、範囲ループは自動的に終了します。
package main

import (
    "fmt"
    "time"
)

func counter(ch chan<- int) {
    for i := 1; i <= 5; i++ {
        ch <- i
        time.Sleep(time.Second)
    }
    close(ch)
}

func main() {
    ch := make(chan int)
    go counter(ch)

    for val := range ch {
        fmt.Println(val)
    }
}

要約すると、Golang のゴルーチンとチャネルは、強力で柔軟な同時プログラミング機能を提供します。 select ステートメント、WaitGroup、バッファー、range キーワードなどの高度な使用法を使用して、ゴルーチンとチャネルの動作をより詳細に制御できます。この記事で示したコード例が、読者がこれらの高度な使用法をより深く理解し、適用するのに役立つことを願っています。

以上がGolang でのゴルーチンとチャネルの高度な使用法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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