使用goroutines无限循环遍历文件。

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

Using goroutines to iterate through file indefinitely

问题

我是你的中文翻译助手,以下是你提供的代码的翻译:

我对Go语言还不熟悉,请原谅我的无知。我试图使用goroutines无限循环地逐行迭代一堆单词列表,但是在尝试这样做时,它并没有迭代或者在中途停止。我应该如何正确地处理这个问题,而不会中断流程?

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. )
  7. var file, _ = os.Open("wordlist.txt")
  8. func start() {
  9. scanner := bufio.NewScanner(file)
  10. for scanner.Scan() {
  11. fmt.Println(scanner.Text())
  12. }
  13. }
  14. func main() {
  15. for t := 0; t < 150; t++ {
  16. go start()
  17. fmt.Scanln()
  18. }
  19. }

谢谢!

英文:

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?

  1. package main
  2. import (
  3. &quot;bufio&quot;
  4. &quot;fmt&quot;
  5. &quot;os&quot;
  6. )
  7. var file, _ = os.Open(&quot;wordlist.txt&quot;)
  8. func start() {
  9. scanner := bufio.NewScanner(file)
  10. for scanner.Scan() {
  11. fmt.Println(scanner.Text())
  12. }
  13. }
  14. func main(){
  15. for t := 0; t &lt; 150; t++ {
  16. go start()
  17. fmt.Scanln()
  18. }
  19. }

Thank you!

答案1

得分: 2

你将file声明为全局变量。在多个goroutine之间共享读写文件状态会导致数据竞争,并且会产生未定义的结果。

最有可能的情况是,读取操作从任何一个goroutine上次读取结束的地方开始。如果那是文件末尾,那么很可能会继续保持文件末尾。但是,由于结果是未定义的,这并不保证。你得到的不稳定结果是由于未定义的行为。

下面是你的程序的修订版本,它声明了一个局部的file变量,并使用sync.Waitgroup来同步所有的go start() goroutine和main goroutine的完成。程序会检查错误。

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "sync"
  7. )
  8. func start(filename string, wg *sync.WaitGroup, t int) {
  9. defer wg.Done()
  10. file, err := os.Open(filename)
  11. if err != nil {
  12. fmt.Println(err)
  13. return
  14. }
  15. defer file.Close()
  16. lines := 0
  17. scanner := bufio.NewScanner(file)
  18. for scanner.Scan() {
  19. lines++
  20. }
  21. if err := scanner.Err(); err != nil {
  22. fmt.Println(err)
  23. return
  24. }
  25. fmt.Println(t, lines)
  26. }
  27. func main() {
  28. wg := &sync.WaitGroup{}
  29. filename := "wordlist.txt"
  30. for t := 0; t < 150; t++ {
  31. wg.Add(1)
  32. go start(filename, wg, t)
  33. }
  34. wg.Wait()
  35. }
英文:

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.

  1. package main
  2. import (
  3. &quot;bufio&quot;
  4. &quot;fmt&quot;
  5. &quot;os&quot;
  6. &quot;sync&quot;
  7. )
  8. func start(filename string, wg *sync.WaitGroup, t int) {
  9. defer wg.Done()
  10. file, err := os.Open(filename)
  11. if err != nil {
  12. fmt.Println(err)
  13. return
  14. }
  15. defer file.Close()
  16. lines := 0
  17. scanner := bufio.NewScanner(file)
  18. for scanner.Scan() {
  19. lines++
  20. }
  21. if err := scanner.Err(); err != nil {
  22. fmt.Println(err)
  23. return
  24. }
  25. fmt.Println(t, lines)
  26. }
  27. func main() {
  28. wg := &amp;sync.WaitGroup{}
  29. filename := &quot;wordlist.txt&quot;
  30. for t := 0; t &lt; 150; t++ {
  31. wg.Add(1)
  32. go start(filename, wg, t)
  33. }
  34. wg.Wait()
  35. }

huangapple
  • 本文由 发表于 2021年11月21日 14:34:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/70052373.html
匿名

发表评论

匿名网友

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

确定