Goroutine通道发送数据直到等待组完成

huangapple go评论81阅读模式
英文:

Goroutine channel send data until wait group finishes

问题

我有一个模块,其中包含一个长时间运行的go例程,直到程序结束才会完成。

我有一个for循环,它会生成其他例程,并将数据发送到通道中。

代码很冗长,所以这里有一个基本相同的示例。

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	channel := someFunc()
	//无关的例程
	go func() {
		time.Sleep(1000 * time.Hour)

	}()
	for resp := range channel {
		fmt.Println(resp)
	}

}

func someFunc() chan int {
	var wg sync.WaitGroup
	t := make(chan int, 10)
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8}
	for _, i := range arr {
		wg.Add(1)

		go func(i int) {
			defer wg.Done()
			time.Sleep(time.Duration(i) * time.Second)

			t <- i

		}(i)
	}
	wg.Wait()
	close(t)
	return t
}

移除等待组和close()(没有这个会导致程序无限运行)会导致程序无限运行,但是有它们会阻塞通道直到所有例程完成。如何在不使程序无限运行的情况下向通道发送数据?

PS:长时间运行的例程在一个我无法控制的导入模块中。

英文:

I have module that has a long running go routine in it that doesn't complete until the end of the program.

I have a for loop that spawns other routines that feed into the channel.

The code is bulky so here is an example that does basically the same thing.

package main

import (
	&quot;fmt&quot;
	&quot;sync&quot;
	&quot;time&quot;
)

func main() {
	channel := someFunc()
	//unrelated routine
	go func() {
		time.Sleep(1000 * time.Hour)

	}()
	for resp := range channel {
		fmt.Println(resp)
	}

}

func someFunc() chan int {
	var wg sync.WaitGroup
	t := make(chan int, 10)
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8}
	for _, i := range arr {
		wg.Add(1)

		go func(i int) {
			defer wg.Done()
			time.Sleep(time.Duration(i) * time.Second)

			t &lt;- i

		}(i)
	}
	wg.Wait()
	close(t)
	return t
}

Removing the wait groups and close() (not having this causes the program to run forever) causes the program to run forever, but having them blocks the channel until all routines finish. How can I send data to the channel without making the program run indefinitely?

PS: the long running routine is in an imported module I do not have control over.

答案1

得分: 1

这个最好的方法是通过添加另一个go例程来实现。这样可以使程序在异步等待关闭程序。

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	channel := someFunc()
	//无关的例程
	go func() {
		time.Sleep(1000 * time.Hour)

	}()
	for resp := range channel {
		fmt.Println(resp)
	}

}

func someFunc() chan int {
	var wg sync.WaitGroup
	t := make(chan int, 10)
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8}
	for _, i := range arr {
		wg.Add(1)

		go func(i int) {
			defer wg.Done()
			time.Sleep(time.Duration(i) * time.Second)

			t <- i

		}(i)
	}
	go func() {
		defer close(t)

		wg.Wait()

	}()
	return t
}
英文:

The best way to do this is by adding another go routine. This allows the program to asynchronously wait to close the program.

package main

import (
	&quot;fmt&quot;
	&quot;sync&quot;
	&quot;time&quot;
)

func main() {
	channel := someFunc()
	//unrelated routine
	go func() {
		time.Sleep(1000 * time.Hour)

	}()
	for resp := range channel {
		fmt.Println(resp)
	}

}

func someFunc() chan int {
	var wg sync.WaitGroup
	t := make(chan int, 10)
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8}
	for _, i := range arr {
		wg.Add(1)

		go func(i int) {
			defer wg.Done()
			time.Sleep(time.Duration(i) * time.Second)

			t &lt;- i

		}(i)
	}
	go func() {
		defer close(t)

		wg.Wait()

	}()
	return t
}

huangapple
  • 本文由 发表于 2022年8月17日 06:18:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/73380951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定