2011-11-22 3 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가 수신되지 않을 이유 . 수신 goroutine이 완료 될 때까지 주 스레드를 잠자기 수있는 방법이 있어야합니다. 또한 수신자와 발신자가 모두 10 개의 숫자를 전송한다는 사실을 알지 못한다. goroutine 중 하나는 다른 하나가 작업을 끝내면 막아야합니다. 어떻게해야할지 모르겠다.

EDIT1 : 여기

는 두 개의 채널을 구현하고, 이동 루틴은 서로 사이에 앞뒤로의 int를 보냅니다. 하나는 응답자 (responder)로 지정되며, 응답자는 int를받은 후 보내고 int로만 응답합니다. 응답자는받은 int에 2를 더한 다음 다시 보냅니다.

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. 그것은 멋지다 ..하지만, 내가 실제로하고 싶은 일은 일상적인 루틴을 받기 위해 int를 보낸다. 그리고 그것으로부터 int를 받는다. 의미는 양방향 통신 채널입니다. 가능한가? – Arpssss

+2

send 루틴은 마지막 정수를 보낸 후 채널을 닫아야하며 수신자는 채널에서 새 값을 수신 할 때 닫힌 채널을 확인해야합니다. http://golang.org/doc/go_spec.html#Close – mkb

+1

@Arpssss : 그것을 위해서는 두 개의 채널이 필요합니다. – mkb

2

데이비드 그레이의 수정 작동하지만 9 항상 수신되지 않는 이유에 대한 설명은 주석에 맞지 않을 것이다 :

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에서 실행 출력입니다!

송신 측의 goroutine이 채널의 값을 송신하면, 수신 측의 goroutine이 그 값을 수신 할 때까지 블록한다. 그 시점에서 차단 해제됩니다. 이동 스케줄러는 수신 goroutine에 아무 것도 인쇄 할 수 없도록하기 전에 거의 즉시 main에서 돌아올 수 있습니다. GOMAXPROCS를 1보다 큰 값으로 설정하면 주 goroutine이 활성화되어있는 동안 수신 goroutine이 차단되지 않으므로 발생 빈도가 줄어 듭니다.

모든 goroutines이 완료 될 때까지 반환에서 주요 중지 할 경우이 같은 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, 따라서 메인은 완전히 차단 해제되어서 그냥 돌아오고 프로그램이 종료됩니다! 나는 분명히이 실수를 범했습니다. 그러나 런타임은 여러분이 기대하는 것처럼 모든 goroutines가 아닌 주요 goroutine과 만 조인합니다.