goroutines 的执行顺序
goroutines order of execution
我正在尝试理解这段代码,不确定为什么第二次执行在第一次执行之前。如果有人真的能帮我解决这个问题就太好了!
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
的调用以不同的顺序打印。当执行 goroutines 时,因为它们是并发操作,你无法保证它们何时会执行 and/or 完成。您需要使用各种标准库包或通道本身来同步并发 运行ning goroutines 的执行。
例如(通过利用通道的阻塞特性,您可以做类似的事情):
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)
}
}
我正在尝试理解这段代码,不确定为什么第二次执行在第一次执行之前。如果有人真的能帮我解决这个问题就太好了!
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
的调用以不同的顺序打印。当执行 goroutines 时,因为它们是并发操作,你无法保证它们何时会执行 and/or 完成。您需要使用各种标准库包或通道本身来同步并发 运行ning goroutines 的执行。
例如(通过利用通道的阻塞特性,您可以做类似的事情):
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)
}
}