Я не знаком с GO. У меня есть следующий код устаревшего кода.Goroutine ведет себя по-разному в Windows и Linux
var db *sql.DB
func init() {
go feedChan()
connString := os.Getenv("DB_CONN")
var err error
db, err = sql.Open("postgres", connString)
if err != nil {
log.Fatalf("Failed to connect to database at %q: %q\n", connString, err)
}
// confirm connection
if err = db.Ping(); err != nil {
log.Fatalf("Unable to ping database at %q: %q\n", connString, err)
}
}
func feedChan() {
selectQuery, err := db.Prepare(`
SELECT id, proxy
FROM proxy
WHERE fail_count < 2
ORDER BY date_added DESC, last_used ASC, fail_count ASC
LIMIT 5
`)
....
Следующий код работает над linux. Но это не будет работать на окна с ошибкой ноль на
selectQuery, err := db.Prepare(`
Какой смысл для меня, так как БД инициализируется после запуска feedChan goroutine. Что для меня не имеет смысла, так это то, почему он работает на Linux.
Итак, вопрос в том, почему этот код работает в Linux без ошибок?
Да, obv, если инициализировать после его работы. Это не мой вопрос. Я запускаю его много на linux и никогда не получаю эту ошибку. Но как только я запускаю на windows-ноль ошибку (которая исчезает, если перемещение db init после goroutine). Поэтому я хочу понять, почему он никогда не производит эту ошибку в Linux, но 100% на Windows. – Aldarund
Вы пытались спать после 'go feedChan()'? Может быть, несколько секунд, чтобы убедиться, что процедура запускается до 'db' готова. Было бы интересно посмотреть, все ли работает в Linux. – beatngu13
@ Aldarund, как и в любом случае UB, такой вопрос не имеет смысла. Это UB, так что все может случиться. Однажды он может сломаться на Linux, он может работать на нем каждый раз, или ваш компьютер может стать живым и убежать от вас. Это не имеет значения. У вашего кода все еще есть UB. Он имеет два потока выполнения, которые пытаются получить доступ к ресурсу без какой-либо синхронизации - 'func init()' и 'func feedChan()'. В этот момент все может случиться, потому что это состояние гонки между двумя потоками. – creker