我正在尝试同时处理文件中的行,但是由于某些原因,我似乎得到不一致的结果。我的代码的简化版本如下:

  var wg sync.WaitGroup
  semaphore := make(chan struct{}, 2)
  lengths:= []int{}

  for _, file := range(args[1:]){
    // Open the file and start reading it
    reader, err := os.Open(file)
    if err != nil {
      fmt.Println("Problem reading input file:", file)
      fmt.Println("Error:", err)
      os.Exit(0)
    }
    scanner := bufio.NewScanner(reader)
    // Start streaming lines
    for scanner.Scan() {
      wg.Add(1)
      text := scanner.Text()
      semaphore <- struct{}{}
      go func(line string) {
          length := getInformation(line)
          lengths = append(lengths, length)
          <-semaphore
          wg.Done()
      }(text)
    }
  }
  wg.Wait()
  sort.Ints(lengths)
  fmt.Println("Lengths:", lengths)
getInformation函数只是返回行的长度。然后,我将那条线添加到数组中。我遇到的问题是,当我对同一个文件多次运行时,数组中的项目数不同。我以为自从我使用waitGroup以来,所有行都将被处理,因此lengths的内容将是相同的,但是事实并非如此。有人可以在这里看到我做错了吗?

最佳答案

lengths = append(lengths, length)正在同时执行。这是不安全的,并且会引起问题,例如缺少 slice 中的条目。您可以通过将append调用包装在互斥体中来解决此问题,或者让gorountines将结果发布到通道中,并在一个位置将其收集到一个 slice 中。

09-08 04:57