2

2つの奇妙なことがあります。

  1. スライスで 1000 個の数字を作成しましたが、246 しか表示されません。

  2. 「log.Println("hey")」という行を削除すると、なぜ 0 しか出力されないのですか?

同期の問題があるかもしれないことは知っていますが、これまで並行プログラムを作成したことがないので、推奨できる記事はありますか?

import (
      "log"
      "runtime"
)

func main() {

  count := 1000
  slice := make([] int,count)
  for i := 0; i <= count-1; i++ {
   slice[i] =i
  }
  for _,v := range slice{
    go echo(v)
  }
  log.Println("hey")//if delete this line,it just print 0
  runtime.Gosched()
}


func echo(v int) {
  log.Println(v)
}
4

2 に答える 2

3

メインルーチンが完了する前に go ルーチンが実行されるという保証はありません。メイン ルーチンが完了すると、プログラムは、作成したすべての go ルーチンが完了する (または開始する) のを待たずに終了します。

これを修正する最も簡単な方法は、同期チャネルを割り当て、それを各エコー インスタンスに渡し、ログ ステートメントの後にトークンを書き込むことです。次に、メイン スレッドは、count戻る前にそのチャネルからトークンを読み取る必要があります。

于 2013-11-22T07:08:44.740 に答える
3

メインの go ルーチンを終了すると、既に実行されている go ルーチンを待機しません。実行中の go ルーチンを同期する必要があります。私の経験では、sync.WaitGroupが適切な一般的なソリューションです。

遊び場

import (
    "log"
    "sync"
)

func main() {

    count := 1000
    slice := make([]int, count)
    for i := 0; i <= count-1; i++ {
        slice[i] = i
    }
    wg := new(sync.WaitGroup)
    for _, v := range slice {
        wg.Add(1)
        go echo(v, wg)
    }
    wg.Wait()
}

func echo(v int, wg *sync.WaitGroup) {
    defer wg.Done()
    log.Println(v)
}
于 2013-11-22T09:00:11.880 に答える