2011-11-22 115 views
0

我嘗試在GO中寫一個簡單的代碼,其中兩個去例程(發送和接收)互相發送整數。我給出下面的代碼。任何人都可以幫助我爲什麼這個程序的輸出是[無輸出]。是否有任何愚蠢的錯誤(對不起,我是新的GO)?Go編程語言代碼錯誤

package main 

func Send (in1 <-chan int, out1 chan<- int) { 

       i := 2 
     out1 <- i 
    print(i, "\n") 
} 

func Receive (in <-chan int, out chan<- int) { 

     i := <-in 
     print(i, "\n") 
     out <- i 
} 


func main() { 

     for i := 0; i < 10; i++ { 
     ch1 := make(chan int) 
     ch := make(chan int) 
      go Send (ch1 , ch) 
     go Receive (ch , ch1) 
     ch = ch1 
     ch1 = ch 
     } 

} 
+0

在發佈前修正您的縮進。 –

回答

2

如何:

package main 

func Send (ch chan<- int) { 
    for i := 0; i < 10; i++ { 
     print(i, " sending\n") 
     ch <- i 
    } 
} 

func Receive (ch <-chan int) { 
    for i := 0; i < 10; i++ { 
     print(<-ch, " received\n") 
    } 
} 

func main() { 
    ch := make(chan int) 
    go Receive(ch) 
    Send(ch) 
} 

的這個時候我就golang.org運行它的輸出是:

0 sending 
0 received 
1 sending 
2 sending 
1 received 
2 received 
3 sending 
4 sending 
3 received 
4 received 
5 sending 
6 sending 
5 received 
6 received 
7 sending 
8 sending 
7 received 
8 received 
9 sending 

我不知道爲什麼9從未收到。應該有一些方法來睡主線程,直到Receive goroutine完成。另外,接收者和發送者都知道他們將發送10個號碼,這是不雅觀的。當其他人完成工作時,其中一間公用事業機構應該關閉。我不知道該怎麼做。

EDIT1:

這裏是雙通道的實現,旅途程序發送整數來回海誓山盟之間。一個被指定爲響應者,它在接收到一個int後才發送和int。響應者只需在接收到的int中添加兩個,然後將其發回。

package main 

func Commander(commands chan int, responses chan int) { 
    for i := 0; i < 10; i++ { 
     print(i, " command\n") 
     commands <- i 
     print(<-responses, " response\n"); 
    } 
    close(commands) 
} 

func Responder(commands chan int, responses chan int) { 
    for { 
     x, open := <-commands 
     if !open { 
      return; 
     } 
     responses <- x + 2 
    } 
} 

func main() { 
    commands := make(chan int) 
    responses := make(chan int) 
    go Commander(commands, responses) 
    Responder(commands, responses) 
} 

當我golang.org運行它的輸出是:

0 command 
2 response 
1 command 
3 response 
2 command 
4 response 
3 command 
5 response 
4 command 
6 response 
5 command 
7 response 
6 command 
8 response 
7 command 
9 response 
8 command 
10 response 
9 command 
11 response 
+0

謝謝David Grayson。這很酷..但是,我真正想要做的Send例程發送int來接收例程,並從它接收int。意味着雙向溝通渠道。可能嗎 ? – Arpssss

+2

發送例程應在發送最後一個整數後關閉通道,接收方在從通道接收新值時應檢查一個封閉通道:http://golang.org/doc/go_spec.html#Close – mkb

+1

@Arpssss:你需要兩個頻道。 – mkb

2

大衛·格雷森的修復工作,但爲什麼9並不總是收到的解釋將不適合評論!

當發送goroutine發送通道上的值時,它會阻塞,直到接收goroutine收到它爲止。那時,它被解鎖了。去程序員可能會在幾乎立即返回主程序之前給接受程序員一個打印任何東西的機會。如果將GOMAXPROCS設置爲大於1的值,則發生頻率降低的頻率較低,因爲在主要goroutine處於活動狀態時,接收goroutine不會被阻塞。

如果你想從返回,直到所有夠程完成後停止主,你可以從Receive()返回一個通道,這樣的:

package main 

import "fmt" 

func Send(ch chan<- int) { 
    for i := 0; i < 10; i++ { 
     fmt.Println(i, " sending") 
     ch <- i 
    } 
    close(ch) 
} 

func Receive(ch <-chan int) (<-chan bool) { 
    done := make(chan bool) 
    go func() { 
     for { 
      i, ok := <-ch 
      if !ok { 
       break 
      } 
      fmt.Println(i, " received") 
     } 
     done <- true 
    }() 
    return done 
} 

func main() { 
    ch := make(chan int) 
    d := Receive(ch) 
    Send(ch) 
    _ = <-d 
} 

至於爲什麼你的輸出是在你原來的例子空:你做兩個goroutines,因此主要完全暢通,所以它只是返回,程序退出!我肯定也犯了這個錯誤,但是運行時只會與主要的goroutine結合,而不是像所有的goroutine一樣。