2017-09-06 10 views
-2

にチャンネルを使用します。Goが、私は印刷に私のコードをしたい交互に印刷

12AB34CD56EF78GH910IJ 

が、それは印刷します。

12AB3456CDEF78910GHIJ 

私はとても混乱していますし、私はそれが奇妙だと思います。

package main 

import (
    "fmt" 
    "sync" 
) 

func main() { 
    numdone := make(chan int) 
    var wg sync.WaitGroup 
    wg.Add(1) 
    go func() { 
      defer wg.Done() 
      data := []byte("ABCDEFGHIJ") 
      for i := 0; i < 10; i = i + 2 { 
        <-numdone 
        fmt.Printf("%c", data[i]) 
        fmt.Printf("%c", data[i+1]) 
      } 
    }() 

    wg.Add(1) 
    go func() { 
      defer wg.Done() 
      for i := 1; i < 11; i = i + 2 { 
        fmt.Printf("%d", i) 
        fmt.Printf("%d", i+1) 
        numdone <- i 
      } 
    }() 

    wg.Wait() 
} 
+0

私は、出力順序を保証するためにチャネルを使用している、と期待通りの出力ではありません。 –

+2

あなたのgoルーチン#1はチャネルを読み込みますが、それが印刷できるようになる前にルーチン#2がスケジュールされ、出力の3456が見えるように次の番号セットが出力されます。 – Ravi

答えて

1

上記のコメントをお読みください。同期するには、ちょうどミューテックスを使用して、それがうまくいく:

package main 

import (
    "fmt" 
    "sync" 
) 

var mu sync.Mutex 

func main() { 
    numdone := make(chan int) 
    var wg sync.WaitGroup 
    wg.Add(1) 
    go func() { 
     defer wg.Done() 
     data := []byte("ABCDEFGHIJ") 
     for i := 0; i < 10; i = i + 2 { 
      <-numdone 
      fmt.Printf("%c", data[i]) 
      fmt.Printf("%c", data[i+1]) 
      mu.Unlock() 
     } 
    }() 

    wg.Add(1) 
    go func() { 
     defer wg.Done() 
     for i := 1; i < 11; i = i + 2 { 
      mu.Lock() 
      fmt.Printf("%d", i) 
      fmt.Printf("%d", i+1) 
      numdone <- i 
     } 
    }() 

    wg.Wait() 
} 

遊び場:https://play.golang.org/p/71Dv0iKTy_

+0

それは本当に動作し、私はそれが2つのchannel.thanksで多く行うことができることを見つける! –

+0

はい、最初の実行ルーチンで印刷後に2番目のチャネルを読み取ります。しかし、コードを読みやすく理解しやすいようにすることができます。そのため、ミューテックスを使用するほうがよいでしょう。 – Ravi

+2

これはどうですか? https://play.golang.org/p/kfn9bhqAmY 1つのチャンネルとミューテックスはありませんか? – usil

関連する問題