おめでとうございます。新しい人物として、並行性とそれが並列性とどのように違うのかを理解することは良いことです。
同時実行
同時実行は片手で空気中のいくつかのボールをジャグリングジャグラーのようなものです。どんなに多くのボールがジャグリングしていても、いつでも1本のボールだけが手を触れる。
並列
ジャグラーが並行して別の手でより多くのボールをジャグリング起動すると、私たちは、同時に実行されている2つの同時プロセスを持っています。彼らは利用できるコンピューティングコアとGOMAXPROCS
されている変数のセットに応じて、同時と自動並列両方だから
ゴルーチンは素晴らしいです。
片手バック片手、シングル入り、同時ジャグラージャグラーに
。想像してみれば、手がmain
ルーチンである "hello"、 "world"、 "mars"の3つのボールをそれぞれジャグリングすることを想像してみてください。
var balls = []string{"hello", "world", "mars"}
func main() {
go say(balls[0])
go say(balls[1])
go say(balls[2])
}
以上適切に、
func main() {
for _, ball := range balls {
go say(ball)
}
}
3つのボールは空気順次に投げられると、ジャグラーは単純にすぐに手を後退させます。つまり、main
ルーチンは、投げられた最初のボールが手に落ちる前に終了します。恥、ボールはちょうど地面に落ちる。悪いショー。
ボールを手に戻すには、ジョグラーが彼にが待っていることを確認する必要があります。これは、彼の手が投げられたボールを追跡してカウントし、それぞれが着陸したときに知ることができる必要があることを意味します。
最も簡単な方法は、sync.WaitGroupを使用することです:
import (
"fmt"
"time"
"sync"
)
var balls = []string{"hello", "world", "mars"}
var wg sync.WaitGroup
func main() {
for _, ball := range balls {
// One ball thrown
wg.Add(1)
go func(b string) {
// Signals the group that this routine is done.
defer wg.Done()
// each ball hovers for 1 second
time.Sleep(time.Duration(1) * time.Second)
fmt.Println(b)
// wg.Done() is called before goroutine exits
}(ball)
}
// The juggler can do whatever he pleases while the
// balls are hanging in the air.
// This hand will come back to grab the balls after 1s.
wg.Wait()
}
WaitGroup
は簡単です。ゴルーチンが生成されると、「バックログカウンタ」にWaitGroup.Add(1)
が追加され、WaitGroup.Done()
と呼ぶとカウンタが減少します。バックログが0になると、すべてのゴルーチンが完了し、WaitGroup
が待機を停止する(そしてボールをつかむ)ことを意味します。
同期にチャネルを使用するのは問題ありませんが、チャネルを使用するとコードが複雑で理解しにくい場合には、特に使用可能な並行ツールを使用することをお勧めします。
https://gobyexample.com/goroutines – elithrar