Проблема с fmt.Println не соответствует порядку печати нитей - PullRequest
0 голосов
/ 18 мая 2018

Рассмотрим следующий код

package main

import (  
    "fmt"
    "runtime"
    "sync"
)

func main() {
    messages := make(chan bool)
    var wg sync.WaitGroup
    var x = 1000

    wg.Add(runtime.NumCPU())
    for i := 0; i < runtime.NumCPU(); i++ {
        go func(x int) {
            defer wg.Done()
            var i = 0
            for i < x {
                i += 1
                fmt.Println(i * i)
            }
            messages <- true
        }(x)
    }

    go func() {
        for i := range messages {
            fmt.Println(i)
        }
    }()

    wg.Wait()
}

И следующую последнюю пару строк вывода

980100
982081
984064
true
988036
990025
992016
994009
996004
998001
1000000

Так как message <- true всегда находится в конце цикла for и

    for i := range messages {
        fmt.Println(i)
    }

печатает после того, как канал получает сообщение.

Я ожидаю, что true будет печататься всегда в конце, как

988036
990025
992016
994009
996004
998001
1000000
true

Но я считаю, что это только иногда вернопочему это так?

1 Ответ

0 голосов
/ 18 мая 2018

То, что вы делаете:

  1. Запустите количество процедур, равное числу процессоров в вашей системе.
  2. Запустите одну дополнительную программу, которая читает и печатаетзначения из канала messages.
  3. Дождитесь завершения выполнения процедур из # 1
  4. Выход

Поскольку вы ожидаете только первую партиюиз-за завершения процедур, нет гарантии, что все (или даже любые) значения messages будут напечатаны до завершения программы.

...