与并发功能不一致的结果?

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


  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是相同的,但事实并非如此。谁能看到我在这里做错了什么?


茅侃侃
浏览 78回答 1
1回答

ITMISS

正在lengths = append(lengths, length)同时执行。这是不安全的,会导致切片丢失条目等问题。您可以通过将追加调用包装在互斥锁中来解决此问题,或者让 gorountines 将它们的结果发布到一个通道并有一个地方将它们收集到一个切片中。
打开App,查看更多内容
随时随地看视频慕课网APP