2014-08-28 6 views
1

는 소수의 예 내가 이해하는 코드이 예에서 채널은 어떻게 작동합니까? 이것은

prime := <-ch 

채널 입력을 기다리고의 라인과 프라임에 할당

package main 

func Generate(ch chan<- int) { 
    for i := 2; ; i++ { 
    ch <- i 
    } 
} 

func Filter(in <-chan int, out chan<- int, prime int) { 
    for { 
    i := <-in 
    if i%prime != 0 { 
     out <- i 
    } 
    } 
} 

func main() { 
    ch := make(chan int) 
    go Generate(ch) 
    for i := 0; i < 10; i++ { 
    prime := <-ch 
    print(prime, "\n") 
    ch1 := make(chan int) 
    go Filter(ch, ch1, prime) 
    ch = ch1 
    } 
} 

체입니다. 모든 숫자가 인쇄되지 않는 이유는 11

ch1 := make(chan int) 
go Filter(ch, ch1, prime) 
ch = ch1 

이 모든 숫자가 2에서 인쇄이 마지막 3 줄을 제거하면 그래서, 다음 문이 줄을 무엇

print(prime, "\n") 

를 호출 할 때 do ch = ch1? 이 루프의 각 반복에서 동일한 채널 아니기 때문에

감사

+1

컨텍스트 : http://golang.org/doc/play/sieve.go. 또한 http://blog.onideas.ws/eratosthenes.go에서 최적화되었습니다. – VonC

+0

@VonC 링크에 감사드립니다.인용 된 기사에는 중급이지만 중요한 개선 단계 인 [연기] (http://stackoverflow.com/a/8871918/849891)에 대한 아이디어가 없습니다. 또 다른 중요한 최적화 (연기와 관련이있다.)는 피드백 루프를 깨뜨림으로써 (블로그가 언급 한) [기억력 감소] (http://stackoverflow.com/a/13895347/849891)이다. 이렇게하면 작은 버퍼 (파이썬 버전 [여기] (http://stackoverflow.com/a/10733621/849891) - 코드의 4 번째 줄 참조)를 가진 소수 생성 채널의 타워를 가질 수 있습니다. –

+0

@WillNess는 언뜻 보면 잘 보입니다. – VonC

답변

2

귀하의 코드의 출력은 다음과 같습니다 :

2 
3 
5 
7 
11 
13 
17 
19 
23 
29 

그래서 절차는 다음과 같이이다 : 여기

당신에게 더 의미가 있습니다 그것을 작성하는 또 다른 방법입니다

전 = 0,

prime := <-ch 이후, 소수 = 2, 채널 = {3}; go Filter(ch, ch1, prime)

, Filter0 같은 마크 함수 Filter0 채널 in는 3,4,5,6 ... 그리고 3,5,7 될 것이다 out 채널 것 ...;

ch = ch1 이후, So ch = {3}, 이는 3,5,7이 될 것입니다.

I = 1,

prime := <-ch 이후 프라임 = 3, CH는 {5}, 왜 ch5있다 = 왜냐하면 지금 ch 마지막 루프에서 ch1이다; go Filter(ch, ch1, prime)

, Filter1 같은 마크 함수 Filter1 채널 in는 5,7,9,11 ... 그리고 5,7,11 될 것이다 out 채널 것 ...;

ch = ch1 이후 So ch = {3}, 이는 5,7,11가됩니다.

i = 2, 동일.

어떻게 출력하나요?

1

모든 숫자가 인쇄되지 않은 이유입니다. 새로운 채널 ch1을 만들고 ch에서 ch1 값을 필터링 한 다음 ch1에 ch를 할당하여 다음 반복 채널이 이전 반복 (ch1이라고 함)의 새 채널이되고 그 값이 필터에 의해 필터링되었습니다 goroutine.

for i := 0; i < 10; i++ { 
    prime := <-ch 
    print(prime, "\n") 
    oldch := ch   //here oldch references the old channel 
    ch = make(chan int) //and here ch is replaced with a new channel 
    go Filter(oldch, ch, prime) //and here a filter is applied to values from oldch to ch 
}