Haskell: TVar: предотвращение голода

Я рассматриваю возможность использования TVar для хранения некоторого состояния в веб-приложении (которое может быть воссоздано при перезапуске). Тем не менее, спорные аспекты TVar меня беспокоят. Кажется, что частые краткосрочные транзакции могут истощать более длинные транзакции, постоянно прерывая их. Кроме того, поскольку более продолжительные транзакции продолжают перезапускаться, это увеличит нагрузку на ЦП, что приведет к дальнейшему увеличению длины этих транзакций. В конце концов я чувствую, что это может привести к тому, что сервер станет полностью не отвечающим.

Учитывая это, у меня есть следующие вопросы:

(1) Может ли TVar (или другой тип данных) использовать блокировки, а не одновременные попытки / повторные попытки.

(2) Может ли TVar (или другой тип данных) иметь какой-либо другой механизм конфликта, то есть "разрешить выполнение транзакций в течение секунды перед выполнением другой транзакции", или, по крайней мере, некоторая гарантия, что транзакции в конечном итоге завершатся (то есть алгоритм конкуренции, который предотвращает голодание для более длительные транзакции).

3 ответа

Решение

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

Если вы действительно обеспокоены этим, подумайте об использовании флага TVar. Установите его в false и проверьте, что это false в начале каждой дешевой транзакции, вызывая retry иначе. Затем просто установите для него значение true, прежде чем вступать в длительную транзакцию, и установите для него значение false при выходе. С другой стороны, вы можете просто охранять свое состояние за TMVar, Ваше длительное вычисление принимает tmvar атомарно, делает то, что чувствует, а затем возвращает его. Другие транзакции полностью выполняются в рамках одной фактической транзакции STM.

Помните также, что длительная транзакция STM - своего рода хитрый зверь. Из-за лени вы можете положить дорогостоящее значение в переменную дешево. Вы также можете очень быстро прочитать "снимок" данных из целого ряда переменных. Чтобы получить действительно длительную транзакцию, вам нужно прочитать из целого ряда переменных, а затем на основе прочитанного вычислить, в какие переменные вы собираетесь записывать новые значения (или читать значения из), а также это вычисление. должен быть дорогим. Скорее всего, вы даже не в этом сценарии для начала!

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

Конечно, голодание может привести к значительной потере производительности, но только при условии, что такие крупные транзакции действительно необходимы. Один принцип дизайна, который я стараюсь помнить, заключается в использовании TVars на низком уровне детализации. Например, вместо того, чтобы положить весь Data.Map в TVar, что может вызывать конфликт при каждом обновлении записи, вы можете использовать более удобную для STM структуру данных, например, скиплисты [1].

[1] http://hackage.haskell.org/package/tskiplist

Это было написано как комментарий к одному из комментариев Клинтона к ответу Питерса. Но это стало долго.

Предположим, у вас есть два банковских счета: A и B. Каждый из них защищен своей собственной блокировкой. Теперь у вас есть две транзакции: первая переводит деньги из A в B, а вторая из B в A. Каждая берет сначала блокировку исходного счета, а затем целевого счета, переводит деньги и снимает блокировки. Если вам не повезет, две транзакции будут заблокированы, и с этими двумя учетными записями ничего не будет сделано. Если вы сделаете это в STM, они будут работать друг за другом. Если у вас бесконечно много первого рода, они могут голодать во второй транзакции. Но вы все еще много сделали. Пока с блокировкой ничего не происходит.

STM гарантирует отсутствие гонок данных с TVars! Никак нет. С блокировкой вы можете прийти к такому выводу после очень тщательной проверки вашего кода. И каждая добавленная вами строка может полностью лишить вас законной силы.

Другие вопросы по тегам