2017-09-06 52 views
-2

我想我的代碼打印:隨時隨地使用通道交替打印

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

你去例行程序#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

它確實有效,我發現它可以通過兩個channel.thanks很多! –

+0

是的,在第一次執行程序中打印後讀取第二個通道。但是,您可能希望保持代碼易於閱讀和理解,因此使用互斥鎖可能是更好的選擇。 – Ravi

+2

這個怎麼樣。 https://play.golang.org/p/kfn9bhqAmY單通道,無互斥? – usil