英文:
Using goroutines to iterate through file indefinitely
问题
我是你的中文翻译助手,以下是你提供的代码的翻译:
我对Go语言还不熟悉,请原谅我的无知。我试图使用goroutines无限循环地逐行迭代一堆单词列表,但是在尝试这样做时,它并没有迭代或者在中途停止。我应该如何正确地处理这个问题,而不会中断流程?
package main
import (
"bufio"
"fmt"
"os"
)
var file, _ = os.Open("wordlist.txt")
func start() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
func main() {
for t := 0; t < 150; t++ {
go start()
fmt.Scanln()
}
}
谢谢!
英文:
I'm new to Go so please excuse my ignorance. I'm attempting to iterate through a bunch of wordlists line by line indefinitely with goroutines. But when trying to do so, it does not iterate or stops half way through. How would I go about this in the proper manner without breaking the flow?
package main
import (
"bufio"
"fmt"
"os"
)
var file, _ = os.Open("wordlist.txt")
func start() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
func main(){
for t := 0; t < 150; t++ {
go start()
fmt.Scanln()
}
}
Thank you!
答案1
得分: 2
你将file
声明为全局变量。在多个goroutine之间共享读写文件状态会导致数据竞争,并且会产生未定义的结果。
最有可能的情况是,读取操作从任何一个goroutine上次读取结束的地方开始。如果那是文件末尾,那么很可能会继续保持文件末尾。但是,由于结果是未定义的,这并不保证。你得到的不稳定结果是由于未定义的行为。
下面是你的程序的修订版本,它声明了一个局部的file
变量,并使用sync.Waitgroup
来同步所有的go start()
goroutine和main
goroutine的完成。程序会检查错误。
package main
import (
"bufio"
"fmt"
"os"
"sync"
)
func start(filename string, wg *sync.WaitGroup, t int) {
defer wg.Done()
file, err := os.Open(filename)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
lines := 0
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines++
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
return
}
fmt.Println(t, lines)
}
func main() {
wg := &sync.WaitGroup{}
filename := "wordlist.txt"
for t := 0; t < 150; t++ {
wg.Add(1)
go start(filename, wg, t)
}
wg.Wait()
}
英文:
You declare file
as a global variable. Sharing read/write file state amongst multiple goroutines is a data race and will give you undefined results.
Most likely, reads start where the last read from any of the goroutines left off. If that's end-of-file, it likely continues to be end-of-file. But, since the results are undefined, that's not guaranteed. Your erratic results are due to undefined behavior.
Here's a revised version of your program that declares a local file
variable and uses a sync.Waitgroup
to synchronize the completion of all the go start()
goroutines and the main
goroutine. The program checks for errors.
package main
import (
"bufio"
"fmt"
"os"
"sync"
)
func start(filename string, wg *sync.WaitGroup, t int) {
defer wg.Done()
file, err := os.Open(filename)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
lines := 0
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines++
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
return
}
fmt.Println(t, lines)
}
func main() {
wg := &sync.WaitGroup{}
filename := "wordlist.txt"
for t := 0; t < 150; t++ {
wg.Add(1)
go start(filename, wg, t)
}
wg.Wait()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论