Предотвращение чрезмерной загрузки ЦП Golang фонового процесса - PullRequest
0 голосов
/ 07 мая 2020

Я пишу программу Go, которая наблюдает за файлами и запускает системную команду, если один из файлов изменился. Пока все работает хорошо. У меня есть вопросы относительно моего основного "бесконечного" l oop, потому что я не хочу, чтобы он занимал все ресурсы системного процессора:

runtime.GOMAXPROCS(1)
for {
    updatedFiles, _ := GetWatchMap(config)
    if !reflect.DeepEqual(filesToWatch, updatedFiles) {
        start := time.Now()
        _, _ = colorstring.Println(fmt.Sprintf(" [yellow] ⬇ Update detected[white] at [green]%s[white] > updating...", start.Format("15:04:05")))
        _, _ = Update(config)
        end := time.Now()
        elapsed := end.Sub(start)
        _, _ = colorstring.Println(fmt.Sprintf("  [green]✅  Done![white] in [yellow]%.2f[white] second(s).", elapsed.Seconds()))
        filesToWatch = updatedFiles
    } else {
        time.Sleep(config.SleepTime)
    }
}

Итак, я установил GOMAXPROCS, поэтому он использует только «1 CPU / Core», и я добавил настраиваемое время сна в ветке else.

Без времени ожидания htop показывает, что процесс занимает 100% процессорного времени (я предполагаю, что это 100% одного ядра?) Независимо от того, вызываю я runtime.GOMAXPROCS(1) или нет.

Если я использую время сна 30 мс на моем компьютере (MacMini i7, 12 Core), htop сообщает о 20% загрузке ЦП процессом, что кажется нормальным, но я предполагаю, что это будет зависеть от компьютера, на котором запущена программа.

Что здесь лучше всего?

1 Ответ

3 голосов
/ 07 мая 2020

GOMAXPROCS делает не то, что вы думаете. Из документа о времени выполнения пакета:

Переменная GOMAXPROCS ограничивает количество потоков операционной системы, которые могут одновременно выполнять код Go уровня пользователя. Нет ограничений на количество потоков, которые могут быть заблокированы в системных вызовах от имени кода Go; они не учитываются при ограничении GOMAXPROCS.

Ограничивает потоки ОС. Если ваш код не использует горутины, которые могли бы быть запланированы для потоков ОС, ограничение количества потоков буквально ничего не делает . Просто удалите материал GOMAXPROCS, он ничего не делает. (Если вы установите для GOMAXPROCS значение 12, у вас будет не более 12 потоков ОС, фактически выполняющих код горутины; если у вас есть только одна горутина, ограничивающая количество потоков ОС, на которых она может работать, это oop.)

Все вы можете не зацикливаться на занятости, как это было с time.Sleep (). В зависимости от ваших требований вы можете регулярно вызывать фактический код, например, через time.Ticker. Не существует единой "передовой практики" (за исключением того, что нельзя возиться с GOMAXPROCS).

...