2016-07-02 1 views
3

나는 3 개의 goroutine 체인을 설정하고 있는데, 각 입력에는 출력 채널이 있습니다. goroutine은 입력 채널을 닫을 때까지 읽습니다. 값을 증가시키고 출력 채널로 보냅니다. 그러나,이 출력 교착 아래 프로그램 :이 Go 프로그램이 중단되는 이유는 무엇입니까?

goroutine 'one': 1 
goroutine 'two': 2 
goroutine 'three': 3 
goroutine 'one': 10 
goroutine 'two': 11 
goroutine 'one': 100 
fatal error: all goroutines are asleep - deadlock! 

코드 : 출력 채널에서 읽고 루프에 도달하지 않기 때문에

package main 

import (
    "fmt" 
) 

func int_channel(id string, i chan int, o chan int) { 
    defer close(o) 

    for x := range i { 
    fmt.Printf("goroutine '%s': %d\n", id, x) 
    o <- x + 1 
    } 

    fmt.Println("done") 
} 

func main() { 
    c0 := make(chan int) 
    c1 := make(chan int) 
    c2 := make(chan int) 
    c3 := make(chan int) 

    go int_channel("one", c0, c1) 
    go int_channel("two", c1, c2) 
    go int_channel("three", c2, c3) 

    c0 <- 1 
    c0 <- 10 
    c0 <- 100 
    c0 <- 1000 
    c0 <- 10000 
    c0 <- 100000 
    close(c0) 

    fmt.Println("Sent all numbers to c0") 

    for x := range c3 { 
    fmt.Printf("out: %d\n", x) 
    } 
} 

답변

4

그것은, 따라서 채널 "emptyed"되지 중지되고 각 채널에 값이 쓰여지면 아무런 진전이 이루어지지 않고 프로그램이 중단됩니다. 그것은 다른 goroutine의 입력에 기록 수정하려면 즉

func main() { 
    c0 := make(chan int) 
    c1 := make(chan int) 
    c2 := make(chan int) 
    c3 := make(chan int) 

    go int_channel("one", c0, c1) 
    go int_channel("two", c1, c2) 
    go int_channel("three", c2, c3) 

    go func(){ 
    c0 <- 1 
    c0 <- 10 
    c0 <- 100 
    c0 <- 1000 
    c0 <- 10000 
    c0 <- 100000 
    fmt.Println("Sent all numbers to c0") 
    close(c0) 
    }() 


    for x := range c3 { 
    fmt.Printf("out: %d\n", x) 
    } 
} 

IOW는 광고 c0 <- 1가 실행될 때, 값이 throught를 세 cannels 흐르고 c3에서 끝나지만 때문에 리더 루프가 아직 도달하지

, 그것은 단지 "거기 앉아있다". 그런 다음 c0 <- 10 행이 실행되고 c3에 쓸 수 없으므로이 값은 c2으로 끝납니다. 이전 값은 여전히 ​​남아있어 쓰기를 차단합니다. 따라서 라인 c0 <- 100이 실행되면 모든 채널이 가득 차서 더 이상 진행할 수 없습니다.

+0

이제는 분명해 보인다. :) Go 동시성 모델에 여전히 익숙해지고있다. 감사! –

+0

또 다른 대안은'c0'을 버퍼링 된 채널로 만들고, 모든 초기 "데이터 충만 (stuffing of data)"을 수용 할 수있는 충분한 용량을 갖도록하는 것입니다. – Vatine

1

귀하는시기 적절하게 c3을 읽지 않습니다. 너무 많은 값을 c0에 보내고 있습니다. C1,

send 1 on c0 => recv 1 on c1 => send 2 on c2 => 
     recv 2 on c2 => send 3 on c3 => recv 3 on c3 

send 10 on c0 => recv 10 on c1 => send 11 on c2 => 
     recv 11 on c2 => send 12 on c3 -- // c3 still hasn't been read 
              // from and so send 
              // operation blocks here. 

C0과 결국 블록을 전송하는 모든 때까지 계속받을 C2 : 그래서 채널 사이의 통신은 다음과 같이 발생합니다. 해결책은 @ ain의 대답을 참조하십시오.