英文:
How do I use Go routines in this example?
问题
我有以下的代码片段。我创建了一个通道,最多从给定目录中获取15个文件名。我认为我可以创建多个goroutine,其中一个用于在通道上产生条目,另一个用于消费它们。消费者应该打印从通道中获取的内容。
我的程序执行时没有打印任何内容,我怀疑这是因为消费者例程正在休眠 - 难道不是为每次for循环迭代启动一个新的goroutine吗?难道最终不应该有一些从通道中打印的内容吗?
func (u *uniprot) produce(n string) {
u.namesInDir <- n
}
func (u *uniprot) consume() {
fmt.Println(<-u.namesInDir)
}
func (u *uniprot) readFilenames(dirname string) {
u.namesInDir = make(chan string, 15)
dir, err := os.Open(dirname)
errorCheck(err)
names, err := dir.Readdirnames(0)
errorCheck(err)
for _, n := range names {
go u.produce(n)
go u.consume()
}
}
英文:
I have the following code snippet. I create a channel that takes 15 filenames at most from a given directory. I thought that I could create goroutines where one produces entries on a channel, and another consumes them. The consumer should print things taken from the channel.
My program executes without printing and I suspect that this is because the consumer routine is sleeping - isn't a new go routine started for each iteration of the for-loop? Shouldn't there eventually be something to print from the channel?
func (u* uniprot) produce(n string) {
u.namesInDir <- n
}
func (u* uniprot) consume() {
fmt.println(<-u.namesInDir)
}
func (u* uniprot) readFilenames(dirname string) {
u.namesInDir = make(chan string, 15)
dir, err := os.Open(dirname)
errorCheck(err)
names, err := dir.Readdirnames(0)
errorCheck(err)
for _, n := range names {
go u.produce(n)
go u.consume()
}
}
答案1
得分: 5
你需要等待goroutine完成。
为了查看问题,在for循环的末尾加上time.Sleep
。
要正确修复问题,可以使用sync.WaitGroup。
以下是一个可能的示例(未经测试):
import "sync"
func (u *uniprot) produce(n string, wg *sync.WaitGroup) {
defer wg.Done()
u.namesInDir <- n
}
func (u *uniprot) consume(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println(<-u.namesInDir)
}
func (u *uniprot) readFilenames(dirname string) {
u.namesInDir = make(chan string, 15)
dir, err := os.Open(dirname)
errorCheck(err)
names, err := dir.Readdirnames(0)
errorCheck(err)
wg := new(sync.WaitGroup)
for _, n := range names {
wg.Add(2)
go u.produce(n, wg)
go u.consume(wg)
}
wg.Wait()
}
英文:
You need to wait for the go routines to finish.
To see the problem put a time.Sleep
at the end of the for loop.
To fix properly use a sync.WaitGroup
Here is an example of how it might work (untested)
import "sync"
func (u *uniprot) produce(n string, wg *sync.WaitGroup) {
defer wg.Done()
u.namesInDir <- n
}
func (u *uniprot) consume(wg *sync.WaitGroup) {
defer wg.Done()
fmt.println(<-u.namesInDir)
}
func (u *uniprot) readFilenames(dirname string) {
u.namesInDir = make(chan string, 15)
dir, err := os.Open(dirname)
errorCheck(err)
names, err := dir.Readdirnames(0)
errorCheck(err)
wg := new(sync.WaitGroup)
for _, n := range names {
wg.Add(2)
go u.produce(n, wg)
go u.consume(wg)
}
wg.Wait()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论