ホームページ  >  記事  >  バックエンド開発  >  Go 言語の WaitGroups とは何ですか?使い方?

Go 言語の WaitGroups とは何ですか?使い方?

青灯夜游
青灯夜游転載
2023-03-17 20:09:481994ブラウズ

待機グループとは何ですか?次の記事では、Go 言語の WaitGroups を理解し、WaitGroups の使用方法を紹介します。

Go 言語の WaitGroups とは何ですか?使い方?

#待機グループとは何ですか?

WaitGroups は、ゴルーチンを同期する効率的な方法です。あなたが家族と一緒に車で旅行していると想像してください。あなたのお父さんは、食べ物を買ったり、トイレに行くために、ストリップ モールやファストフード レストランに立ち寄ります。 Horizo​​n に向かう前に、全員が戻るまで待ったほうがよいでしょう。 WaitGroups はこれを行うのに役立ちます。

WaitGroups は、標準ライブラリの sync パッケージを呼び出すことによって定義されます。

var wg sync.WaitGroup

それでは、WaitGroup とは何ですか? WaitGroup は、プログラムが待機する必要がある goroutine の数に関する特定の情報を含む構造体です。これは、待機する必要がある ゴルーチン の数を含むグループです。

WaitGroups には、AddDoneWait という 3 つの最も重要なメソッドがあります。

  • 追加: 待機する必要がある goroutine の総数に追加します。
  • 完了: 待機する必要があるゴルーチンの総数から 1 を減算します。
  • Wait: 待機するゴルーチンがなくなるまでコードの続行をブロックします。

WaitGroups の使用方法

コードの一部を見てみましょう:

package main

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

func main() {
    var wg sync.WaitGroup
    wg.Add(1)

    go func() {
        defer wg.Done()

        fmt.Println(time.Now(), "start")
        time.Sleep(time.Second)
        fmt.Println(time.Now(), "done")
    }()

    wg.Wait()
    fmt.Println(time.Now(), "exiting...")
}
2022-08-21 17:01:54.184744229 +0900 KST m=+0.000021800 start
2022-08-21 17:01:55.184932851 +0900 KST m=+1.000210473 done
2022-08-21 17:01:55.18507731 +0900 KST m=+1.000354912 exiting...
  • 最初に # を初期化します。 ##WaitGroup wg のインスタンス。
  • 次に、
  • goutine が完了するまで待機するため、wg に 1 を追加します。
  • 次に、この
  • ゴルーチンを実行します。 goroutine 内で、wg.Done() への遅延呼び出しを行い、待機する goroutine の数を確実に減分します。これを行わないと、コードは goroutine が完了するまで永遠に待機することになり、デッドロックが発生します。
  • goroutine 呼び出しの後、WaitGroup が空になるまでコードをブロックする必要があります。これを行うには、wg.Wait() を呼び出します。

なぜチャネルの代わりに WaitGroups を使用するのでしょうか?

WaitGroups の使用方法がわかったので、自然に次の疑問が生じます。なぜチャネルの代わりに WaitGroups を使用するのでしょうか?

私の経験に基づくと、理由はいくつかあります。

  • WaitGroups はより直感的になる傾向があります。コードを読んで WaitGroup が表示されると、そのコードが何をしているのかがすぐにわかります。メソッド名は明確で要点を捉えています。ただし、チャネルの場合、それがそれほど明確ではない場合があります。チャネルを使用するのは賢明ですが、複雑なコードを読むと理解するのが面倒になることがあります。
  • 場合によっては、チャネルを使用する必要がありません。たとえば、次のコードを見てみましょう:
  •  var wg sync.WaitGroup
    
      for i := 0; i < 5; i++ {
          wg.Add(1)
          go func() {
              defer wg.Done()
    
              fmt.Println(time.Now(), "start")
              time.Sleep(time.Second)
              fmt.Println(time.Now(), "done")
          }()
      }
    
      wg.Wait()
      fmt.Println(time.Now(), "exiting...")
この

goutine が他の goroutine とデータ通信を行っていないことがわかります。 goroutine が 1 回限りのジョブであり、結果を知る必要がない場合は、WaitGroup を使用することをお勧めします。ここで、次のコードを見てください:

  ch := make(chan int)

  for i := 0; i < 5; i++ {
      go func() {
          randomInt := rand.Intn(10)
          ch <- randomInt
      }()
  }

  for i := 0; i < 5; i++ {
      fmt.Println(<-ch)
  }

ここでは、

goroutinechannel にデータを送信しています。このような場合、WaitGroup は冗長になるため、使用する必要はありません。受信側ですでに十分なブロックが行われている場合、goroutine が完了するまで待つ必要はありません。

WaitGroups は、groutines の待機を処理するために特別に使用されます。チャネルの主な目的はデータを通信することだと思います。 WaitGroup を使用してデータを送受信することはできませんが、channel を使用して groutines を同期することはできます。

最後に、正解はありません。面倒かもしれませんが、それはあなたとあなたが働くチーム次第です。どの方法が最善であっても、答えが間違っているということはありません。私は個人的には同期に

WaitGroups を使用することを好みますが、状況は異なる場合があります。最も直感的に感じられるものを選択してください。

注意すべき点が 1 つあります。

場合によっては、

WaitGroup インスタンスを goroutine に渡す必要があります。異なる goroutine を処理するために複数の WaitGroup が存在する場合もあれば、設計上の選択である場合もあります。理由が何であれ、必ず次のように WaitGroup にポインターを渡してください。

var wg sync.WaitGroup

for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(wg *sync.WaitGroup) {
        defer wg.Done()

        fmt.Println(time.Now(), "start")
        time.Sleep(time.Second)
        fmt.Println(time.Now(), "done")
    }(&wg)
}

wg.Wait()
fmt.Println(time.Now(), "exiting...")

その理由は、Go が値渡し言語であるためです。これは、関数に引数を渡すたびに、Go はその引数をコピーし、元のオブジェクトの代わりにそれを渡すことを意味します。この場合に起こることは、

WaitGroup オブジェクト全体がコピーされることです。つまり、groutin はまったく異なる WaitGroup を処理することになります。 wg.Done() は、元の wg から減算するのではなく、goutine にのみ存在するそのコピーを減算します。

概要

WaitGroups を使用すると、groutines を簡単に同期でき、コードが正しい時間に実行されるようになります。チャネルは同期にも使用できますが、通常は WaitGroups の方が直感的で読みやすいです。 WaitGroup を使用する場合は、コピーの問題を防ぐために、ポインタを WaitGroup に正しく渡してください。どの方法を選択する場合でも、最も直感的で、あなたとあなたのチームにとって最適なものを選択してください。

推奨学習: Golang チュートリアル

以上がGo 言語の WaitGroups とは何ですか?使い方?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。