2017-03-09 6 views
0

테스트 코드를 작성했지만이 결과가 왜 나왔는지 이해할 수 없습니다.golang : coroutines 및 채널에 이상한 문제가 발생했습니다.

sub() 업데이트하거나 내가 10 이동 루틴 con()를 시작 채널 값

send 1 = counter++ 
send 0 = return counter 

에 따라 counter를 반환해야합니다. 그들은 채널에 많은 1을 보냅니다 (이 증가 카운터)
1 초를 기다렸다가 0을 채널로 보냅니다. 어떤 가치를 가져야합니까? 내가 처음 생각

, 나는 「랜덤 "값, 을 얻을하지만 난 100000를 얻을 지금은 변경

(OK 10 배 10000는 1 초보다 빠른)

for i:=0; i < 10; i++ { 

for i:=0; i < 10000; i++ { 

지금 내 반환되는 값은 1

왜!?

이제 fmt.Println(counter)main()의 주석 처리에서 제거하십시오. 당신은 카운터 행실을보고이 "임의의"번호 2 개 채널

package main 

import (
    "fmt" 
    "time" 
) 

var ch chan int = make(chan int) 
var counter int 

func main() { 
    go sub() 

    for i:=0; i < 10; i++ { //change to 10000 
     go con() 
    } 

    time.Sleep(1000 * time.Millisecond) 

    ch <- 0 
    fmt.Println(<- ch) 
    //fmt.Println(counter) //uncomment this 
} 

func sub() { 
    for c := range ch { 
     if c == 0 { ch <- counter } 
     if c == 1 { counter++ } 
    } 
} 

func con() { 
    for i := 0; i < 10000; i++ { 
     ch <- 1 
    } 
} 
+0

은'main' 또는'sub' 첫번째 끌어 여부를 알 수 없기 때문이다 'ch'에서. 명령과 데이터를 전송할 때 다른 채널을 사용하십시오. – zerkms

+0

2 채널이 작동합니다! 하지만 로직은 어디에 있습니까? ch는 을 보내기 위해 con()와 병렬로 10x를 사용하고 sub()로 1x를 사용하고 receive 용으로는 1x 만 사용합니다. 나는 이것을 이해하지 못한다. – john49384

+0

아 ... 잠깐, 천천히 알아 ... 너를 zerkms 고맙다. – john49384

답변

0

,이 일이 있기 때문에 :

package main 

import (
    "fmt" 
    "time" 
) 

var ch chan int = make(chan int) 
var ch2 chan int = make(chan int) 
var counter int 

func main() { 
    go sub() 

    for i:=0; i < 10000; i++ { //change to 10000 
     go con() 
    } 

    time.Sleep(1000 * time.Millisecond) 

    ch2 <- 0 
    fmt.Println(<- ch2) 
    //fmt.Println(counter) //uncomment this 
} 

func sub() { 
    for ;; { 
     select { 
     case <- ch: 
      counter++ 
     case <- ch2: 
      ch2 <- counter 
     } 
    } 
} 

func con() { 
    for i := 0; i < 10000; i++ { 
     ch <- 1 
    } 
}