У меня есть несколько goroutines в моей программе, каждый из которых делает вызовы fmt.Println
без какой-либо явной синхронизации. Является ли это безопасным (т.е. Будет ли каждая строка отображаться отдельно без повреждения данных), или мне нужно создать еще один goroutine с синхронизацией специально для обработки печати?
Безопасно ли для более чем одного goroutine печатать на stdout?
Ответ 1
Нет, это небезопасно, хотя иногда вы можете не замечать никаких проблем. IIRC, пакет fmt пытается быть в безопасности, поэтому возможно смешение какого-то рода может произойти, но, надеюсь, не произойдет никакого сбоя процесса.
Это пример более универсального правила документации Go: все небезопасно для одновременного доступа, если не указано иное или где оно очевидно из контекста.
Можно иметь безопасную версию хорошего подмножества функций fmt.Print *, используя пакет журнала с небольшой начальной настройкой.
Ответ 2
Все fmt
возвращается к w.Write()
, как можно видеть здесь. Поскольку вокруг нет блокировки, все возвращается к реализации Write()
. Поскольку до сих пор нет блокировки (для Stdout как минимум), нет гарантии, что ваш вывод не будет смешан.
Я бы рекомендовал использовать глобальную процедуру журнала.
Кроме того, если вы просто хотите записывать данные, используйте пакет log
, который правильно блокирует доступ к выходу.
Для справки см. .
Ответ 3
Общие методы (fmt.printLine) небезопасны. Тем не менее, существуют методы.
log.Logger является "goroutine safe": https://golang.org/pkg/log/#Logger
Что-то вроде этого создаст регистратор stdout, который можно безопасно использовать из любой процедуры.
logger := log.New(os.Stdout, "", 0)