Golang中如何解决计算顺序执行而非并发的问题

Golang中如何解决计算顺序执行而非并发的问题 https://play.golang.org/p/yMvf6pPEo0C

我是Go语言的新手,正在尝试理解Go中的并发模式。 我尝试并发计算一组数字的平方,但每次它都是按顺序计算的,即从0到25依次进行。我是不是做错了什么? 任何帮助都将不胜感激。先谢谢了。

5 回复

现在我明白了。感谢您的回复。

更多关于Golang中如何解决计算顺序执行而非并发的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


执行速度如此之快,以至于一个工作线程完成了所有计算,而其他工作线程甚至还没有开始。休眠操作给了其他工作线程执行任务的机会。

感谢您的回复。您能解释一下为什么在读取或写入之间进行休眠会改变顺序吗?

计算速度如此之快,以至于元素的顺序得以保持。尝试在从 jobs 读取和向 results 写入之间加入休眠:

	for n := range jobs {
		time.Sleep(10 * time.Millisecond)
		results <- square(n)
	}

这样顺序就会改变:

$ ./square
1
4
0
25
9
16
49
64
...

参见 https://play.golang.org/p/P7ek45wtR0-

你遇到的问题是因为 fmt.Println 在循环中直接调用,它会阻塞并顺序输出。要看到并发效果,需要让每个 goroutine 独立完成工作后再收集结果。以下是修改后的代码:

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	results := make(chan int, 26)

	for i := 0; i <= 25; i++ {
		wg.Add(1)
		go func(x int) {
			defer wg.Done()
			results <- x * x
		}(i)
	}

	go func() {
		wg.Wait()
		close(results)
	}()

	for res := range results {
		fmt.Println(res)
	}
}

关键修改:

  1. 使用 sync.WaitGroup 等待所有 goroutine 完成
  2. 通过 channel 收集结果,避免输出阻塞并发执行
  3. 使用带缓冲的 channel 防止死锁

运行时会看到输出顺序是随机的,证明计算是并发的。如果需要保持顺序,可以在收集结果后排序:

package main

import (
	"fmt"
	"sort"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	mu := sync.Mutex{}
	results := make([]int, 0, 26)

	for i := 0; i <= 25; i++ {
		wg.Add(1)
		go func(x int) {
			defer wg.Done()
			res := x * x
			mu.Lock()
			results = append(results, res)
			mu.Unlock()
		}(i)
	}

	wg.Wait()
	sort.Ints(results)
	
	for _, res := range results {
		fmt.Println(res)
	}
}
回到顶部