Подтвердить что ты не робот

Разница между TVar и TMVar

Я видел, что TVar представляет собой простой контейнер, а TMVar совпадает с MVar, то есть имеет блокировку и т.д., но внутри монады STM. Мне интересно, почему это необходимо, поскольку идея STM заключается в том, чтобы сделать блокировки ненужными.

Итак, какой именно использовать, если у вас есть тип типа [Handle] список дескрипторов сокетов, которые вы хотите использовать между потоками, созданными forkIO?

4b9b3361

Ответ 1

Это не вопрос блокировки, это о том, что означает ссылка:

  • TVar является изменчивой ссылкой внутри STM, представляющей общее общее состояние. Вы создаете его, сохраняя значение, вы можете читать и писать ему и т.д. Это очень похоже на IORef или STRef (что в любом случае одинаково).

  • TMVar - ссылка на слот, который потоки могут использовать для связи. Он может быть создан с сохранением значения или пустым. Вы можете поместить в него значение, которое, если оно уже заполнено, пока кто-то еще не опустошит его; или вы можете извлечь из него значение, которое, если оно уже пустое, пока кто-то не заполнит его. Это, очевидно, похоже на MVar, но для многих распространенных применений проще было бы рассматривать его как одноэлементную очередь, используемую для сообщающейся пары производитель/покупатель.

Короче говоря, TVar является общим общим состоянием, используйте его, если вы хотите получать атомные обновления данных из произвольных мест. TMVar - это примитив синхронизации, используйте его, если вы хотите, чтобы поток подождал, пока что-то станет доступным, а другой ждет чего-то, что необходимо.

Также обратите внимание на TChan, который реализуется примерно как два места хранения TVar в связанном списке, где каждая прямая ссылка также является TVar и работает как неограниченная очередь для связи.

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

Ответ 2

Различия между TVar и TMVar не так велики, как они выглядят - определенно не сопоставимы с различиями между IORef и MVar.

Хотя MVar действительно обеспечивает некоторую блокировку безопасности потоков, TMVar ничего интересного не делает! (без дополнительной блокировки). Все важное значение уже реализовано с помощью STM и TVar, поэтому TMVar a является просто короткой рукой для TVar (Maybe a), снабженной некоторыми хорошими функциями (некоторые из которых блокируют с помощью функции retry),.

Будет ли блокировка с помощью retry совместима с духом STM и устраняет ли это некоторые из преимуществ STM (без взаимоблокировок и т.д.) - это отдельный вопрос, и я хотел бы, чтобы кто-то более опытен, чтобы ответить на него.