Несовместимые результаты с параллельной функцией? - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь обрабатывать строки из файла одновременно, но по некоторым причинам я получаю противоречивые результаты. Упрощенная версия моего кода ниже:

  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 будет одинаковым, но, похоже, это не так. Кто-нибудь может увидеть, что я здесь делаю не так?

1 Ответ

0 голосов
/ 04 сентября 2018

lengths = append(lengths, length) выполняется одновременно. Это небезопасно и приведет к таким проблемам, как отсутствие записей в срезе. Вы можете исправить это, обернув вызовы добавления в мьютекс, или же gorountines опубликует свои результаты в канале и получит единственное место, которое собирает их в срез.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...