我试图理解这段代码,不确定为什么第二遍在第一遍之前执行。如果有人真的可以帮助我,那就太好了!
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) }
输出:
summing: [4 5 6] 15 summing: [1 2 3] 6
您没有任何内容可以显式同步两个goroutine的顺序。如果运行足够的时间,您将看到调用以fmt.Println不同的顺序进行打印。当执行goroutine时,由于它们是并发操作,因此无法保证它们将何时执行和/或完成。您需要使用各种标准库程序包或通道本身来同步并发运行的goroutine的执行。
fmt.Println
例如(通过利用渠道的封锁性,您可以执行以下操作):
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) }
另一个示例(显然不那么实用,但是在这里查看其他常见的go同步功能),您可以引入一个等待组和一个通道范围:
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) } }