Golang代码优化问题,求大神指点

Golang代码优化问题,求大神指点 你好,

我有两个作为 goroutine 执行的函数:

  1. 第一个函数 f1 仅向通道发送偶数
  2. 第二个函数 f2 仅向同一通道发送奇数。

在主函数中,我想打印这些数字。主函数应按以下顺序打印值: 1 2 3 4 …

我使用了两个通道来同步两个 goroutine(即偶数和奇数)。因此,第一个 goroutine 将发送 0,然后第二个发送 1,第一个再发送 2,依此类推。

你能帮我优化这段代码吗:https://play.golang.org/p/dgVWW8ew2A6 我希望只使用一个通道进行同步。

谢谢


更多关于Golang代码优化问题,求大神指点的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

使用一个单一的通道,在两个 goroutine 之间来回传递一些无关紧要的值。

更多关于Golang代码优化问题,求大神指点的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我已修改我的问题。

我有两个作为 goroutine 执行的函数:

  1. 第一个函数 f1 仅在通道中发送偶数
  2. 第二个函数 f2 仅在同一通道中发送奇数

你好 @petrus

我的问题有所不同。我有两个协程。一个始终生成偶数,另一个始终生成奇数,并且两者都会将数字放入同一个通道。

消费者,在我的例子中是主函数,将始终按顺序获取值。这已经在我现有的代码中实现了。

我想优化这段代码。我使用了两个通道来在这两个协程(即偶数和奇数协程)之间进行同步。我想只用一个通道来实现同步。

目前,我使用了三个通道。一个用于存储数字,另外两个用于同步。 期望:我希望只使用两个通道。一个用于存储数字,另一个用于同步。

希望我已经解释清楚了。

使用一个通道进行同步:

package main

import "fmt"

func next(c, m chan int) {
	for {
		n := <-c
		m <- n
		n++
		c <- n
	}
}

func main() {
	m := make(chan int)
	c := make(chan int)
	go next(c, m)
	c <- 1
	go next(c, m)
	for n := range m {
		fmt.Println(n)
		if n >= 20 {
			break
		}
	}
}

https://play.golang.org/p/eAf7y2H8lU7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Prithvipal_Singh:

我想优化这段代码。我使用了两个通道来同步这两个 goroutine,即偶数和奇数。我想使用单个通道进行同步。

目前,我使用了三个通道。一个用于存储数字,另外两个用于同步。 期望:我只想使用两个通道。一个用于存储数字,另一个用于同步。

希望我已经解释清楚了。

不,你解释得并不清楚。你只是在重复你第一篇文章中的内容。

正如你在两篇文章中所要求的,我使用一个通道进行同步,即通道 c。并使用一个通道来存储数字,即通道 m。我使用了两个通道,

m := make(chan int)
c := make(chan int)

Go Playground - The Go Programming Language

你使用了两个通道进行同步,即通道 evenodd。并使用一个通道来存储数字,即通道 ch。你使用了三个通道,

ch := make(chan int)
even := make(chan bool)
odd := make(chan bool)

Go Playground - The Go Programming Language

你可以通过使用一个通道和一个等待组来优化代码,让两个 goroutine 交替向同一个通道发送数字。以下是优化后的代码示例:

package main

import (
	"fmt"
	"sync"
)

func main() {
	ch := make(chan int)
	var wg sync.WaitGroup

	wg.Add(2)

	go func() {
		defer wg.Done()
		for i := 0; i <= 10; i += 2 {
			ch <- i
		}
	}()

	go func() {
		defer wg.Done()
		for i := 1; i <= 10; i += 2 {
			ch <- i
		}
	}()

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

	for num := range ch {
		fmt.Println(num)
	}
}

这个实现使用单个通道 ch 接收来自两个 goroutine 的数字。sync.WaitGroup 用于等待两个发送 goroutine 完成,然后关闭通道。主函数通过 for range 循环从通道中读取并打印数字。

输出结果会交替打印奇数和偶数,但顺序可能不是严格的 1,2,3,4…,因为两个 goroutine 是并发执行的。如果你需要严格的交替顺序,可以使用一个信号通道来控制执行顺序:

package main

import (
	"fmt"
)

func main() {
	ch := make(chan int)
	done := make(chan bool)

	go func() {
		for i := 0; i <= 10; i += 2 {
			ch <- i
			<-done
		}
	}()

	go func() {
		for i := 1; i <= 10; i += 2 {
			<-done
			ch <- i
		}
		close(done)
	}()

	for i := 0; i <= 10; i++ {
		fmt.Println(<-ch)
		if i%2 == 0 {
			done <- true
		}
	}
}

这个版本使用 done 通道来确保严格的交替顺序:偶数 goroutine 发送数字后等待信号,奇数 goroutine 等待信号后发送数字。主函数在接收到偶数后向 done 通道发送信号,确保两个 goroutine 严格交替执行。

回到顶部