править: Я спрашиваю, безопасны ли глобальные переменные в однопоточной веб-платформе как торнадо
Я использую mongoengine orm, который получает соединение с базой данных от глобальной переменной:
_get_db() # gets the db connection
Я также использую торнадо, однопоточную веб-платформу Python. в одном конкретном представлении я должен захватить соединение с базой данных и разыменовать a DBRef
объект [подобный внешнему ключу]:
# dereference a DBRef
_get_db().dereference(some_db_ref)
начиная с соединения, возвращенного _get_db
глобальный var, там возможность коллизии и неправильного значения, возвращенного к неправильному потоку?
Если предположить, что MongoEngine обертывает PyMongo (а я думаю, что это так), тогда все будет в порядке. PyMongo полностью потокобезопасен.
globals, что делает их более или менее потокобезопасными, чем любые другие переменные. Независимо от того, возможен ли сбой операции или возврат неверных результатов при выполнении в разных потоках, рекомендуется защитить данные, совместно используемые потоками.
Если я вас правильно понял, вы спрашиваете, безопасна ли переменная в однопоточной среде. В этом случае, когда данные не разделяются между параллельными процессами, переменная безопасна (в конце концов, нет ничего другого, что могло бы ее прервать).
Потоки всегда должны удерживать GIL при взаимодействии с объектами Python. Пространство имен, содержащее переменные, является объектом Python (либо frameobject, либо dict, в зависимости от типа переменной). Всегда безопасно получать или устанавливать переменные в нескольких потоках. Вы никогда не получите мусорные данные.
Однако обычные условия гонки действительно применяются в отношении того, какой объект вы получаете или какой объект вы заменяете при назначении. Такой оператор, как x + = 1
, не потокобезопасен, потому что другой поток может выполняться между получением и хранилищем, изменяя значение x
, который вы затем перезаписываете.