Нужна ли по-прежнему логическая блокировка при написании программного обеспечения STM?

Я не писал ничего, связанного с STM (Software Transactional Memory), только читал информацию в Интернете. Так вот просто воображаемый пример

Предположим, у нас есть буфер FIFO с максимально допустимым количеством элементов в нем. Таким образом, мы заполняем массив до тех пор, пока не будет достигнуто максимальное количество элементов, и сдвигаем его, когда элементов больше не осталось. При традиционном подходе я бы заблокировал не только фактическое смещение и добавление, но и условное чтение, которое проверяет, достигнут ли максимум. Я должен сделать это, иначе два потока могут симулировать решение, что единственный оставшийся элемент предназначен для них. Так что у меня здесь некая логическая блокировка, не связанная напрямую с писательским конфликтом.

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

Так что мне все еще нужно добавлять «логические» блокировки при написании программного обеспечения, связанного с STM?


stm
person Maksee    schedule 09.06.2013    source источник


Ответы (1)


Вам не нужна никакая логическая блокировка — уж точно не для этого сценария.

Два потока не могут «постоянно замечать», что один слот все еще свободен. Единственный способ отката одного потока — это успешное завершение другого потока, что означает, что последний слот был заполнен.

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

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

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

person MathematicalOrchid    schedule 06.07.2013
comment
Базы данных MVCC, такие как MySQL и PostgreSQL, по-прежнему страдают от взаимоблокировок, и вам все равно нужно понимать семантику блокировок при их использовании в очень сложных параллельных сценариях. Я думал, что STM почерпнул свои идеи из транзакций базы данных, таких как MVCC. Почему STM не страдает от тех же проблем? - person CMCDragonkai; 02.07.2015
comment
1. Текущая реализация STM не использует многоверсионный параллелизм; он использует оптимистическую блокировку. 2. Я не могу говорить о MySQL, но у меня сложилось впечатление, что PostgreSQL никогда не блокируется. В худшем случае ваша транзакция откатывается со слишком старым снимком или с конфликтами записи. - person MathematicalOrchid; 02.07.2015