2016-10-02 5 views
1

나는이 코드를 이해하려고 노력하고 있는데, 왜 두 번째 시도가 첫 번째 코드보다 먼저 실행되는지 모르겠습니다. 누군가가 정말로이 일을 도와 주면 좋을 것 같습니다!골 루틴의 실행 순서

func sum(a []int, c chan int) { 
    fmt.Println("summing: ", a) 
    total := 0 
    for _, v := range a { 
     total += v 
    } 
    //fmt.Println("send to c",total) 
    c <- total // send total to c 
} 
func main() { 
    //a := []int{7, 2, 8,134,23,23,1,23,1234,143, -9, 4, 0, 1234} 

    c := make(chan int) 

    go sum([]int{1,2,3}, c) 
    go sum([]int{4,5,6}, c) 

    x := <-c 
    fmt.Println(x) 
    x = <-c 
    fmt.Println(x) 
} 

는 OUTPUT :

summing: [4 5 6] 
15 
summing: [1 2 3] 
6 

답변

2

당신은 아무것도 명시 적으로 두 goroutines의 순서를 동기화가 없습니다. 이 작업을 충분히 실행하면 fmt.Println에 대한 호출이 다른 순서로 인쇄됩니다. goroutines를 실행할 때 동시 작업이므로 실행할 때 및/또는 완료 할 때 보장 할 수 없습니다. 동시에 실행되는 goroutine의 실행을 동기화하려면 다양한 표준 라이브러리 패키지 또는 채널 자체를 사용해야합니다. 당신은 소개 할 수

func main() { 

    c := make(chan int) 

    go sum([]int{1, 2, 3}, c) 

    //use the channel to block until it receives a send 
    x := <-c 
    fmt.Println(x) 

    //then execute the next routine 
    go sum([]int{4, 5, 6}, c) 

    x = <-c 
    fmt.Println(x) 
} 

또 다른 예 (훨씬 적은 실제, 그러나 여기에서 다른 일반적인 이동 동기화 기능을보고) :

예를 들어

(채널의 차단 특성을 활용하여, 당신은 뭔가를 할 수 있습니다) 대기 그룹 및 채널을 통한 범위 :

func sum(a []int, c chan int, wg *sync.WaitGroup) { 
    defer wg.Done() 
    fmt.Println("summing: ", a) 
    total := 0 
    for _, v := range a { 
     total += v 
    } 
    //fmt.Println("send to c",total) 
    c <- total // send total to c 
} 

func main() { 

    c := make(chan int) 
    wg := new(sync.WaitGroup) 

    //concurrently call the concurrent calls to sum, allowing execution to continue to the range of the channel 
    go func() { 
     //increment the wait group, and pass it to the sum func to decrement it when it is complete 
     wg.Add(1) 
     go sum([]int{1, 2, 3}, c, wg) 
     //wait for the above call to sum to complete 
     wg.Wait() 
     //and repeat... 
     wg.Add(1) 
     go sum([]int{4, 5, 6}, c, wg) 
     wg.Wait() 
     //all calls are complete, close the channel to allow the program to exit cleanly 
     close(c) 
    }() 

    //range of the channel 
    for theSum := range c { 
     x := theSum 
     fmt.Println(x) 
    } 

}