Гарантируется ли переменная подкачка атомарной в Python?

db.collection.find({"createdDate":{$gte:new ISODate("2017-04-14T23:59:59Z"),$lte:new ISODate("2017-04-15T23:59:59Z")}}).count();

Замените collection именем коллекции, которую хотите выполнить запрос

30
задан dhruvbird 12 April 2010 в 15:11
поделиться

2 ответа

Посмотрим:

>>> x = 1
>>> y = 2
>>> def swap_xy():
...   global x, y
...   (x, y) = (y, x)
... 
>>> dis.dis(swap_xy)
  3           0 LOAD_GLOBAL              0 (y)
              3 LOAD_GLOBAL              1 (x)
              6 ROT_TWO             
              7 STORE_GLOBAL             1 (x)
             10 STORE_GLOBAL             0 (y)
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE    

Не похоже, чтобы они атомарны: значения x и y могут быть изменены другим потоком между байт-кодами LOAD_GLOBAL , до или после ROT_TWO и между байт-кодами STORE_GLOBAL .

Если вы хотите поменять местами две переменные атомарно, вам понадобится блокировка или мьютекс.

Для тех, кто хочет эмпирического доказательства:

>>> def swap_xy_repeatedly():
...   while 1:
...     swap_xy()
...     if x == y:
...       # If all swaps are atomic, there will never be a time when x == y.
...       # (of course, this depends on "if x == y" being atomic, which it isn't;
...       #  but if "if x == y" isn't atomic, what hope have we for the more complex
...       #  "x, y = y, x"?)
...       print 'non-atomic swap detected'
...       break
... 
>>> t1 = threading.Thread(target=swap_xy_repeatedly)
>>> t2 = threading.Thread(target=swap_xy_repeatedly)
>>> t1.start()
>>> t2.start()
>>> non-atomic swap detected
54
ответ дан 27 November 2019 в 23:47
поделиться

Да, будет.

Я исправлюсь .

Краген Ситакер пишет:

Кто-то рекомендовал использовать идиому

 спам, яйца = яйца, спам 
 

, чтобы получить потокобезопасный своп. Это действительно работает? (...)
Итак, если этот поток теряет контроль где-то между первым LOAD_FAST
и последним STORE_FAST, значение может быть сохранено другим потоком
{{ 1}} в "b", который затем будет потерян. Ничего не мешает этому
, не так ли?

Нет. В общем, даже простое назначение не обязательно является потокобезопасным , поскольку выполнение этого назначения может вызывать специальные методы объекта , которые сами могут требовать числа {{ 1}} операций. Будем надеяться, что объект будет иметь внутреннюю блокировку своих "состояний" значений, но это не всегда .

Но на самом деле это продиктовано тем, что означает "потокобезопасность" в конкретном приложении, потому что, на мой взгляд, существует много уровней детализации таких {{1} } безопасность, поэтому трудно говорить о "потокобезопасности". Единственное, что интерпретатор Python собирается предоставить вам бесплатно, это то, что встроенный тип данных должен быть защищен от внутреннего повреждения даже при родная резьба. Другими словами, если два потока имеют a = 0xff и a = 0xff00 , a будет в конечном итоге с одним или другое, но не случайно 0xffff , что могло бы быть возможно на некоторых других языках, если не защищен.

С учетом сказанного, Python также имеет тенденцию выполняться таким образом, что вы можете уйти с ужасной массой без формальной блокировки, если вы ' мы готовы немного жить на грани и иметь подразумеваемые зависимости от фактических используемых объектов . Некоторое время назад здесь, в clp, было приличное обсуждение по этому поводу - поищите на groups.google.com тему "Критические разделы и мьютексы" среди других.

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

- - Дэвид

4
ответ дан 27 November 2019 в 23:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: