英文:
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 (
"fmt"
"sync"
"time"
)
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 <- 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 (
"fmt"
"sync"
"time"
)
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 <- i
}(i)
}
go func() {
defer close(t)
wg.Wait()
}()
return t
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论