私は次のコードでいくつかの問題があります。sync.WaitGroupを使用してのベストな方法
package main
import (
"fmt"
"sync"
)
// This program should go to 11, but sometimes it only prints 1 to 10.
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(2)
go Print(ch, wg) //
go func(){
for i := 1; i <= 11; i++ {
ch <- i
}
close(ch)
defer wg.Done()
}()
wg.Wait() //deadlock here
}
// Print prints all numbers sent on the channel.
// The function returns when the channel is closed.
func Print(ch <-chan int, wg sync.WaitGroup) {
for n := range ch { // reads from channel until it's closed
fmt.Println(n)
}
defer wg.Done()
}
は私が指定した場所でのデッドロックを取得します。私は012の代わりにwg.Add(1)
を試して、それは私の問題を解決します。私の信念は、Printer
関数の引数としてチャンネルを正常に送信していないということです。それを行う方法はありますか?最善の解決策は何
func Print(ch <-chan int) {
for n := range ch { // reads from channel until it's closed
fmt.Println(n)
}
}
:へ
go func() {
Print(ch)
defer wg.Done()
}
とPrinter
機能を変更:そうでなければ、私の問題を解決するには、とのgo Print(ch, wg)
ラインを交換していますか?
がそれを手に入れた、私はあることをあなたがアドレスを必要と知らなかったお役に立てば幸いです'WaitGroup'自体の代わりに' Print'に送られました。 私はメソッドが 'WaitGroup'について知る必要はないと同意しますが、とにかくこれを必要としているとします。それでは、星は何ですか?私は 'main'で定義した' WaitGrooup'を選んでいますか?なぜこのコピーはコピーではないのですか? – Sahand
'* sync.WaitGroup'は、' WaitGroup'ではなく 'WaitGroup'へのポインタをコンパイラに伝えます。したがって、コンパイラはあなたにアドレスを与えてメソッドを呼び出すことを期待しています。したがって、 '&wg'です。 – Elwinar
送信者が完了するのを待っていただけで、最後の値が印刷される前にメインのwg.Waitが落ちてしまうので、プリントのウェイトグループを削除できないと思わないでください。また、defer()、defer()関数を終了する理由は、基本的には、これを最後に実行することを意味します。遅れを落とす –