Атомарность в компьютерных науках

Проще говоря, атомарная операция гарантирует, что действие полностью завершится успешно или полностью завершится неудачей. Если пойти дальше, приведенная цитата обеспечивает контекст и точность для описания принципа в правильной терминологии:

В параллельном программировании операция (или набор операций) является атомарной, линеаризуемой, неделимой или непрерывной, если остальной части системы кажется, что она происходит мгновенно.

Атомарность — это гарантия изоляции от параллельных процессов. Кроме того, атомарные операции обычно имеют определение «успех или сбой» — они либо успешно изменяют состояние системы, либо не имеют видимого эффекта.

Атомарность обычно обеспечивается за счет взаимного исключения, будь то на аппаратном уровне, основанном на протоколе когерентности кеша, или на программном уровне с использованием семафоров или блокировок. Таким образом, атомарная операция на самом деле не происходит мгновенно.

В информатике атомарность часто ассоциируется с базами данных и представляет собой букву «A» в ACID, которая описывает набор свойств для транзакций базы данных.

Пример

Типичный пример, используемый для иллюстрации эффекта этого принципа, — перевод денег с одного счета на другой. При переводе 100 долларов со счета Боба на банковский счет Салли было бы катастрофой, если бы деньги были удалены со счета Боба, но не зачислены на счет Салли для Боба и Салли, поскольку это привело бы к потере 100 долларов Салли. Транзакция была бы столь же проблематичной, если бы деньги были добавлены на счет Салли, но не были удалены со счета Боба в банке.

Достижение атомарности

Есть несколько механизмов для достижения атомарности, но для простоты основное внимание будет уделено блокировке. В упрощенном виде это можно увидеть как:

  • Определите места в памяти, к которым будет осуществляться доступ.
  • Создавайте замки на каждой локации.
  • Выполните линейный набор транзакций и сохраните их в новом месте памяти.
  • Дождитесь завершения всех транзакций.
  • В одной транзакции поменяйте местами памяти.

Эта стратегия, вероятно, приведет к невозможности многопоточной операции, но, как уже упоминалось, есть и другие методы.

Атомарные операции в Python

Официальная документация Python дает представление о том, какие операции являются / не являются атомарными.

Довольно интересно отметить, что даже присвоение переменных не гарантирует безопасность и атомарность.

Атомарная операция в сети

При использовании традиционного интерфейса командной строки Cisco IOS линейное применение конфигураций может быть проблематичным. Возьмем, к примеру, создание VTY ACL. Добавление одной строки в новый ACL может привести к неявному отказу и потенциально заблокировать оператор. Естественно, возможность атомарного применения конфигураций имеет очевидные преимущества.

К счастью, по крайней мере с 2007 года появилась функция, называемая «настройка замены», которая заменяет всю конфигурацию Cisco IOS. Более того, это используется в библиотеке NAPALM Python. Чтобы проиллюстрировать эффект, первая попытка не удастся протолкнуть конфигурации и продемонстрировать правильный откат, а вторая попытка будет работать, как задумано.

Первоначально «предполагаемая» конфигурация будет содержать эту надуманную неправильную конфигурацию.

vlan 499
 name printers
!
vlan 5000
 name users

Ошибочно введенный VLAN 5000 вместо 500 будет проблематичным. Давайте посмотрим, как реагирует NAPALM.

>>> import getpass
>>> from napalm import get_network_driver
>>> driver = get_network_driver('ios')
>>> hostname = 'ios-sw1'
>>> username = 'ntc'
>>> password = getpass.getpass()
Password:
>>> device = driver(hostname, username, password)
>>> device.open()
>>> device.load_replace_candidate(filename='ios-sw1')
>>> device.compare_config()
'+vlan 499\n  +name printers\n+vlan 5000\n +name users'
>>> device.commit_config()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/dist-packages/napalm/ios/ios.py", line 533, in commit_config
    raise ReplaceConfigException(msg)
napalm.base.exceptions.ReplaceConfigException: Candidate config could not be applied
Command rejected: Bad VLAN list - character #5 (EOL) delimits a VLAN
number which is out of the range 1..4094.
Failed to apply command vlan 5000
Aborting Rollback.

Rollback failed.Reverting back to the original configuration: flash:-Dec-14-13-05-59.491-0 ...

Total number of passes: 1
Rollback Done

The original configuration has been successfully restored.

>>>

Как видите, сравнение конфигурации указывает на попытку добавить сети VLAN 499 и 5000. Однако при попытке фиксации конфигурации конфигурация прерывается со следующим сообщениемCommand rejected: Bad VLAN list - character #5 (EOL) delimits a VLAN number which is out of the range 1..4094. Сбой вызывает откат и гарантирует, что обе сети VLAN не будут созданы.

Обновление VLAN 5000 до правильного VLAN 500 и повторный запуск процесса приводят к успешной операции.

>>> device = driver(hostname, username, password)

>>> device.open()

>>> device.load_replace_candidate(filename='ios-sw1')

>>> device.compare_config()

'+vlan 499\n  +name printers\n+vlan 500\n +name users'

>>> device.commit_config()

>>>

Это можно дополнительно проверить на коммутаторе, просмотрев конфигурацию.

vlan 499

 name printers

!

vlan 500

 name users

Хотя процессу «конфигурирования и замены», вероятно, не хватает целостности, присущей базе данных PostgreSQL или MySQL, он в значительной степени эффективен при создании атомарной операции.

Заключение

Атомарная операция, как правило, более безопасна и подразумевает ваше намерение, за исключением редких случаев использования. В базах данных это часто обрабатывается транзакциями, и на практике создание собственных атомарных действий часто требует блокировок. Возможно, Йода может лучше всего описать атомарность своей цитатой: «Делай или не делай. Нет никакой попытки ».