Spec-Zone.ru › Haskell 9

GHC.Conc

Copyright (c) The University of Glasgow 1994-2023
License see libraries/base/LICENSE
Maintainer ghc-devs@haskell.org
Stability internal
Portability non-portable (GHC extensions)
Safe Haskell Unsafe
Language Haskell2010

Содержание

  • Разветвление и тому подобное
  • Ожидание
  • Счётчик и лимит выделения памяти
  • TVars
  • Разное

Описание

Основные средства конкурентного программирования.

API этого модуля нестабилен и не предназначен для использования широкой публикой. Если вам абсолютно необходимо от него зависеть, убедитесь, что вы используете жёсткое верхнее ограничение, например, base < 4.X вместо base < 5, поскольку интерфейс может быстро меняться без предупреждения.

data ThreadId Source

A ThreadId is an abstract type representing a handle to a thread. ThreadId is an instance of Eq, Ord and Show, where the Ord instance implements an arbitrary total ordering over ThreadIds. The Show instance lets you convert an arbitrary-valued ThreadId to string form; showing a ThreadId value is occasionally useful when debugging or diagnosing the behaviour of a concurrent program.

Примечание: в GHC, если у вас есть ThreadId, у вас по сути есть указатель на сам поток. Это означает, что сам поток не может быть очищен сборщиком мусора, пока вы не отбросите ThreadId. Исправить этот недостаток, продолжая поддерживать threadStatus, было бы сложно.

Конструкторы

ThreadId ThreadId#
Экземпляры
Подробности о экземплярах
Show ThreadId Source

Since: base-4.2.0.0

Подробности о экземпляре

Defined in GHC.Internal.Conc.Sync

Методы

showsPrec :: Int -> ThreadId -> ShowS Source

show :: ThreadId -> String Source

showList :: [ThreadId] -> ShowS Source

Eq ThreadId Source

Since: base-4.2.0.0

Подробности о экземпляре

Defined in GHC.Internal.Conc.Sync

Методы

(==) :: ThreadId -> ThreadId -> Bool Source

(/=) :: ThreadId -> ThreadId -> Bool Source

Ord ThreadId Source

Since: base-4.2.0.0

Подробности о экземпляре

Defined in GHC.Internal.Conc.Sync

Методы

compare :: ThreadId -> ThreadId -> Ordering Source

(<) :: ThreadId -> ThreadId -> Bool Source

(<=) :: ThreadId -> ThreadId -> Bool Source

(>) :: ThreadId -> ThreadId -> Bool Source

(>=) :: ThreadId -> ThreadId -> Bool Source

max :: ThreadId -> ThreadId -> ThreadId Source

min :: ThreadId -> ThreadId -> ThreadId Source

Разветвление и тому подобное

forkIO :: IO () -> IO ThreadId Source

Создаёт новый поток для выполнения вычисления IO, переданного в качестве первого аргумента, и возвращает ThreadId вновь созданного потока.

Новый поток будет лёгким, несвязанным потоком. Не гарантируется, что внешние вызовы, сделанные этим потоком, будут сделаны каким-либо конкретным потоком ОС; если вам необходимо, чтобы внешние вызовы выполнялись конкретным потоком ОС, используйте forkOS вместо этого.

Новый поток наследует замаскированное состояние родителя (см. mask).

Вновь созданный поток имеет обработчик исключений, который игнорирует исключения BlockedIndefinitelyOnMVar, BlockedIndefinitelyOnSTM и ThreadKilled, и передаёт все другие исключения обработчику неперехваченных исключений.

ВНИМАНИЕ: Исключения в новом потоке не будут переброшены в поток, который его создал. Это означает, что вы можете совершенно не знать о проблеме, если/когда это произойдёт. Возможно, вам стоит использовать библиотеку async вместо этого.

forkIOWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId Source

Как forkIO, но дочернему потоку передаётся функция, которая может использоваться для снятия маски с асинхронных исключений. Эта функция обычно используется следующим образом

 ... mask_ $ forkIOWithUnmask $ \unmask ->
                catch (unmask ...) handler

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

Обратите внимание, что функция unmask, переданная дочернему потоку, должна использоваться только в этом потоке; поведение не определено, если она вызывается в другом потоке.

С момента: base-4.4.0.0

forkOn :: Int -> IO () -> IO ThreadId Источник

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

Аргумент Int задаёт номер возможности (см. getNumCapabilities). Обычно возможности соответствуют физическим процессорам, но точное поведение зависит от реализации. Значение, переданное forkOn, интерпретируется по модулю общего числа возможностей, возвращаемого getNumCapabilities.

Примечание GHC: количество возможностей задаётся параметром +RTS -N при запуске программы. Возможности могут быть закреплены за фактическими ядрами процессоров с помощью +RTS -qa, если это поддерживается подлежащей операционной системой, хотя на практике это обычно не требуется (и может даже снизить производительность в некоторых случаях — рекомендуется экспериментирование).

С момента: base-4.4.0.0

forkOnWithUnmask :: Int -> ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId Источник

Как forkIOWithUnmask, но дочерний поток привязывается к заданному процессору, как с forkOn.

С момента: base-4.4.0.0

numCapabilities :: Int Источник

значение, переданное флагу +RTS -N. Это количество потоков Haskell, которые могут работать истинно одновременно в любой момент времени, и обычно устанавливается равным количеству физических ядер процессора на машине.

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

getNumCapabilities :: IO Int Источник

Возвращает количество потоков Haskell, которые могут работать истинно одновременно (на отдельных физических процессорах) в любой момент времени. Чтобы изменить это значение, используйте setNumCapabilities.

С момента: base-4.4.0.0

setNumCapabilities :: Int -> IO () Источник

Устанавливает количество потоков Haskell, которые могут работать истинно одновременно (на отдельных физических процессорах) в любой момент времени. Переданное в forkOn значение интерпретируется по модулю этого значения. Начальное значение задаётся параметром выполнения +RTS -N.

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

С момента: base-4.5.0.0

getNumProcessors :: IO Int Источник

Возвращает количество ЦП, имеющихся в машине

С момента: base-4.5.0.0

numSparks :: IO Int Источник

Возвращает количество искр в настоящее время в локальном пуле искр

childHandler :: SomeException -> IO () Источник

myThreadId :: IO ThreadId Источник

Возвращает ThreadId вызывающего потока (только GHC).

killThread :: ThreadId -> IO () Источник

killThread вызывает исключение ThreadKilled в заданном потоке (только GHC).

killThread tid = throwTo tid ThreadKilled

throwTo :: Exception e => ThreadId -> e -> IO () Источник

throwTo вызывает произвольное исключение в целевом потоке (только GHC).

Доставка исключений синхронизируется между исходным и целевым потоком: throwTo не возвращается, пока исключение не будет вызвано в целевом потоке. Таким образом, вызывающий поток может быть уверен, что целевой поток получил исключение. Доставка исключений также атомарна относительно других исключений. Атомарность является полезным свойством при работе с проблемами гонок: например, если есть два потока, которые могут убить друг друга, гарантируется, что только один из потоков сможет убить другой.

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

Если целевой поток в настоящее время выполняет вызов к внешней функции, исключение не будет вызвано (и, следовательно, throwTo не вернётся) до завершения вызова. Это имеет место независимо от того, находится ли вызов внутри mask или нет. Однако в GHC вызов к внешней функции может быть помечен как interruptible, в этом случае throwTo заставит RTS попытаться заставить вызов вернуть значение; см. документацию GHC для получения дополнительной информации.

Важное примечание: поведение throwTo отличается от описанного в статье "Асинхронные исключения в Haskell" (http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm). В статье throwTo является асинхронной; но реализация библиотеки использует более синхронный дизайн, в котором throwTo не возвращается до тех пор, пока исключение не будет получено целевым потоком. Компромисс обсуждается в разделе 9 статьи. Как любая блокирующая операция, throwTo поэтому прерывима (см. раздел 5.3 статьи). Однако, в отличие от других прерывимых операций, throwTo всегда прерывима, даже если она фактически не блокируется.

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

Если целевой объект throwTo — это вызывающий поток, то поведение такое же, как у throwIO, за исключением того, что исключение выбрасывается как асинхронное исключение. Это означает, что если есть окружающее чистое вычисление, что имело бы место, если текущая операция IO находится внутри unsafePerformIO или unsafeInterleaveIO, это вычисление не заменяется исключением постоянно, а приостанавливается как если бы оно получило асинхронное исключение.

Обратите внимание, что если throwTo вызывается с текущим потоком как целевым объектом, исключение будет выброшено, даже если поток в настоящее время находится внутри mask или uninterruptibleMask.

par :: a -> b -> b infixr 0 Источник

pseq :: a -> b -> b infixr 0 Источник

runSparks :: IO () Источник

Внутренняя функция, используемая RTS для запуска искр.

yield :: IO () Source

Действие yield позволяет (вынуждает в реализации кооперативной многозадачности) контекстную смену на любой другой в данный момент готовый к выполнению поток (если таковые имеются) и иногда бывает полезно при реализации абстракций конкурентности.

labelThread :: ThreadId -> String -> IO () Source

labelThread сохраняет строку в качестве идентификатора для этого потока. Этот идентификатор будет использоваться в отладочном выводе, чтобы облегчить различение различных потоков (в противном случае у вас будет только адрес объекта состояния потока в куче). Он также генерирует событие в журнале событий RTS.

mkWeakThreadId :: ThreadId -> IO (Weak ThreadId) Source

Создаёт слабую ссылку на ThreadId. Это может быть важно, если вы хотите сохранить ссылку на ThreadId, одновременно позволяя потоку получать исключения семейства BlockedIndefinitely (например, BlockedIndefinitelyOnMVar). Сохранение обычной ThreadId ссылки предотвратит доставку исключений BlockedIndefinitely, потому что ссылка может быть использована как целевой объект для throwTo в любой момент, что разблокирует поток.

Сохранение Weak ThreadId, с другой стороны, не предотвратит получение потоком исключений BlockedIndefinitely. По-прежнему возможно выбросить исключение в Weak ThreadId, но вызывающий код должен использовать deRefWeak сначала, чтобы определить, существует ли поток.

Since: base-4.6.0.0

listThreads :: IO [ThreadId] Source

Список потоков Haskell текущего процесса.

Since: base-4.18

data ThreadStatus Source

Текущее состояние потока

Конструкторы

ThreadRunning

поток в настоящее время готов к выполнению или выполняется

ThreadFinished

поток завершен

ThreadBlocked BlockReason

поток заблокирован на некотором ресурсе

ThreadDied

поток получил необработанное исключение

Примеры реализации
Подробности примеров
Show ThreadStatus Source

Since: base-4.3.0.0

Подробности примера

Определено в GHC.Internal.Conc.Sync

Методы

showsPrec :: Int -> ThreadStatus -> ShowS Source

show :: ThreadStatus -> String Source

showList :: [ThreadStatus] -> ShowS Source

Eq ThreadStatus Source

Since: base-4.3.0.0

Подробности примера

Определено в GHC.Internal.Conc.Sync

Методы

(==) :: ThreadStatus -> ThreadStatus -> Bool Source

(/=) :: ThreadStatus -> ThreadStatus -> Bool Source

Ord ThreadStatus Source

Since: base-4.3.0.0

Подробности примера

Определено в GHC.Internal.Conc.Sync

Методы

compare :: ThreadStatus -> ThreadStatus -> Ordering Source

(<) :: ThreadStatus -> ThreadStatus -> Bool Source

(<=) :: ThreadStatus -> ThreadStatus -> Bool Source

(>) :: ThreadStatus -> ThreadStatus -> Bool Source

(>=) :: ThreadStatus -> ThreadStatus -> Bool Source

max :: ThreadStatus -> ThreadStatus -> ThreadStatus Source

min :: ThreadStatus -> ThreadStatus -> ThreadStatus Source

data BlockReason Source

Краткое описание конструкторов

BlockedOnMVar

блокировано на MVar

BlockedOnBlackHole

блокировано на вычислении, выполняемом другим потоком

BlockedOnException

блокировано в throwTo

BlockedOnSTM

блокировано в retry в транзакции STM

BlockedOnForeignCall

в настоящее время находится во внешнем вызове

BlockedOnOther

блокировано на каком-то другом ресурсе. Без -threaded, ввод/вывод и threadDelay отображаются как BlockedOnOther, с -threaded они отображаются как BlockedOnMVar.

Экземпляры
Подробности о экземплярах
Show BlockReason Source

Since: base-4.3.0.0

Подробности о экземпляре

Определено в GHC.Internal.Conc.Sync

Краткое описание методов

showsPrec :: Int -> BlockReason -> ShowS Source

show :: BlockReason -> String Source

showList :: [BlockReason] -> ShowS Source

Eq BlockReason Source

Since: base-4.3.0.0

Подробности о экземпляре

Определено в GHC.Internal.Conc.Sync

Краткое описание методов

(==) :: BlockReason -> BlockReason -> Bool Source

(/=) :: BlockReason -> BlockReason -> Bool Source

Ord BlockReason Source

Since: base-4.3.0.0

Подробности о экземпляре

Определено в GHC.Internal.Conc.Sync

Краткое описание методов

compare :: BlockReason -> BlockReason -> Ordering Source

(<) :: BlockReason -> BlockReason -> Bool Source

(<=) :: BlockReason -> BlockReason -> Bool Source

(>) :: BlockReason -> BlockReason -> Bool Source

(>=) :: BlockReason -> BlockReason -> Bool Source

max :: BlockReason -> BlockReason -> BlockReason Source

min :: BlockReason -> BlockReason -> BlockReason Source

threadStatus :: ThreadId -> IO ThreadStatus Source

Запрос текущего состояния выполнения потока.

threadCapability :: ThreadId -> IO (Int, Bool) Source

Возвращает номер возможности, на которой в данный момент выполняется поток, и булево значение, указывающее, заблокирован ли поток на этой возможности или нет. Поток блокируется на возможности, если он был создан с помощью forkOn.

Since: base-4.4.0.0

newStablePtrPrimMVar :: MVar a -> IO (StablePtr PrimMVar) Source

Создает StablePtr, который может быть передан в функцию C hs_try_putmvar(). RTS требует StablePtr к базовому MVar#, но StablePtr# может ссылаться только на поднятые типы, поэтому нам приходится жульничать, используя приведение типов.

data PrimMVar Source

Ожидание

threadDelay :: Int -> IO () Source

Приостанавливает текущий поток на заданное количество микросекунд (только GHC).

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

Будьте осторожны, чтобы не превышать maxBound :: Int, что на 32-битных машинах составляет всего 2147483647 мкс, менее 36 минут. Рассмотрите возможность использования Control.Concurrent.Thread.Delay.delay из пакета unbounded-delays.

registerDelay :: Int -> IO (TVar Bool) Source

Изменить значение возвращаемого TVar с начального значения False на True после заданного количества микросекунд. Применяются те же оговорки, что и для threadDelay.

Будьте внимательны, чтобы не превысить maxBound :: Int, которое на 32-битных машинах составляет всего 2147483647 мкс, что меньше 36 минут.

threadWaitRead :: Fd -> IO () Source

Заблокировать текущий поток до тех пор, пока данные не станут доступны для чтения в заданном дескрипторе файла (только для GHC).

Это вызовет IOError, если дескриптор файла был закрыт, пока этот поток был заблокирован. Чтобы безопасно закрыть дескриптор файла, который использовался с threadWaitRead, используйте closeFdWith.

threadWaitWrite :: Fd -> IO () Source

Заблокировать текущий поток до тех пор, пока данные не смогут быть записаны в заданный дескриптор файла (только для GHC).

Это вызовет IOError, если дескриптор файла был закрыт, пока этот поток был заблокирован. Чтобы безопасно закрыть дескриптор файла, который использовался с threadWaitWrite, используйте closeFdWith.

threadWaitReadSTM :: Fd -> IO (STM (), IO ()) Source

Возвращает действие STM, которое можно использовать для ожидания данных для чтения из дескриптора файла. Второе возвращаемое значение — действие IO, которое можно использовать для отмены интереса к дескриптору файла.

threadWaitWriteSTM :: Fd -> IO (STM (), IO ()) Source

Возвращает действие STM, которое можно использовать для ожидания возможности записи в дескриптор файла. Второе возвращаемое значение — действие IO, которое можно использовать для отмены интереса к дескриптору файла.

closeFdWith Source

Аргументы

:: (Fd -> IO ())

Действие низкого уровня, выполняющее реальное закрытие.

-> Fd

Дескриптор файла для закрытия.

-> IO ()

Закрыть дескриптор файла безопасным для конкурентного доступа способом (только для GHC). Если вы используете threadWaitRead или threadWaitWrite для выполнения блокирующего ввода-вывода, вы обязательно должны использовать эту функцию для закрытия дескрипторов файлов, иначе заблокированные потоки могут не быть разблокированы.

Любые потоки, заблокированные на дескрипторе файла с помощью threadWaitRead или threadWaitWrite, будут разблокированы путем выброса исключений IO.

Счётчик и предел выделения памяти

setAllocationCounter :: Int64 -> IO () Source

Каждый поток имеет счётчик выделения памяти, отслеживающий количество выделенной памяти потоком. Счётчик инициализируется нулём, а setAllocationCounter устанавливает текущее значение. Счётчик выделения памяти отсчитывает *вниз*, так что в отсутствие вызова setAllocationCounter его значение является отрицанием количества байтов памяти, выделенной потоком.

С этим счётчиком можно выполнить два действия:

  • Использовать его как простой механизм профилирования, с помощью getAllocationCounter.
  • Использовать его как ограничение ресурсов. См. enableAllocationLimit.

Отслеживание выделения памяти точное только приблизительно до 4Кбайт.

Since: base-4.8.0.0

getAllocationCounter :: IO Int64 Source

Возвращает текущее значение счётчика выделения памяти для текущего потока.

Since: base-4.8.0.0

enableAllocationLimit :: IO () Source

Включает возможность использования счётчика выделения памяти в качестве ограничения для текущего потока. Когда ограничение по выделению памяти включено, если счётчик выделения памяти уменьшится ниже нуля, потоку будет отправлено асинхронное исключение AllocationLimitExceeded. В этом случае счётчик сбрасывается (по умолчанию до 100К, но настраиваемо с помощью опции +RTS -xq) для того, чтобы он мог обработать исключение и выполнить необходимые операции по очистке. Если он исчерпает это дополнительное ограничение, будет отправлено ещё одно исключение AllocationLimitExceeded, и так далее. Как и другие асинхронные исключения, исключение AllocationLimitExceeded откладывается, пока поток находится внутри mask или обработчика исключений в catch.

Обратите внимание, что выделение памяти не связано с *актуальной памятью*, также известной как *резиденцией кучи*. Поток может выделить большое количество памяти и сохранить всё от нуля до всего её объёма. Лучше думать об ограничении выделения как об ограничении *времени CPU*, а не как об ограничении памяти.

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

Since: base-4.8.0.0

disableAllocationLimit :: IO () Source

Отключить обработку лимита выделения памяти для текущего потока.

Since: base-4.8.0.0

TVars

newtype STM a Source

Моноид, поддерживающий атомарные транзакции памяти.

Конструкторы

STM (State# RealWorld -> (# State# RealWorld, a #))
Примеры
Подробности о реализациях
Alternative STM Source

Берёт первое не-retryщее STM действие.

Since: base-4.8.0.0

Подробности о реализации

Определено в GHC.Internal.Conc.Sync

Методы

empty :: STM a Source

(<|>) :: STM a -> STM a -> STM a Source

some :: STM a -> STM [a] Source

many :: STM a -> STM [a] Source

Applicative STM Source

Since: base-4.8.0.0

Подробности о реализации

Определено в GHC.Internal.Conc.Sync

Методы

pure :: a -> STM a Source

(<*>) :: STM (a -> b) -> STM a -> STM b Source

liftA2 :: (a -> b -> c) -> STM a -> STM b -> STM c Source

(*>) :: STM a -> STM b -> STM b Source

(<*) :: STM a -> STM b -> STM a Source

Functor STM Source

Since: base-4.3.0.0

Подробности о реализации

Определено в GHC.Internal.Conc.Sync

Методы

fmap :: (a -> b) -> STM a -> STM b Source

(<$) :: a -> STM b -> STM a Source

Monad STM Source

Since: base-4.3.0.0

Подробности о реализации

Определено в GHC.Internal.Conc.Sync

Методы

(>>=) :: STM a -> (a -> STM b) -> STM b Source

(>>) :: STM a -> STM b -> STM b Source

return :: a -> STM a Source

MonadPlus STM Source

Берёт первое не-retryщее STM действие.

Since: base-4.3.0.0

Подробности о реализации

Определено в GHC.Internal.Conc.Sync

Методы

mzero :: STM a Source

mplus :: STM a -> STM a -> STM a Source

Monoid a => Monoid (STM a) Source

Since: base-4.17.0.0

Подробности о реализации

Определено в GHC.Internal.Conc.Sync

Методы

mempty :: STM a Source

mappend :: STM a -> STM a -> STM a Source

mconcat :: [STM a] -> STM a Source

Semigroup a => Semigroup (STM a) Source

Since: base-4.17.0.0

Подробности экземпляра

Определено в GHC.Internal.Conc.Sync

Методы

(<>) :: STM a -> STM a -> STM a Исходный код

sconcat :: NonEmpty (STM a) -> STM a Исходный код

stimes :: Integral b => b -> STM a -> STM a Исходный код

atomically :: STM a -> IO a Исходный код

Выполнить серию действий STM атомарно.

Использование atomically внутри unsafePerformIO или unsafeInterleaveIO нарушает некоторые гарантии, предоставляемые STM. Это позволяет запускать транзакцию внутри другой транзакции, в зависимости от того, когда вычисляется лямбда-выражение. Если попытка вложенной транзакции имеет место, runtime выбрасывает исключение. Безопасное использование atomically внутри unsafePerformIO или unsafeInterleaveIO возможно, но компилятор не исключает программы, которые могут пытаться выполнить вложенные транзакции, что означает, что программист должен уделять особое внимание предотвращению таких ситуаций.

Однако существуют функции для создания транзакционных переменных, которые всегда можно безопасно вызывать в unsafePerformIO. См.: newTVarIO, newTChanIO, newBroadcastTChanIO, newTQueueIO, newTBQueueIO, и newTMVarIO.

Использование unsafePerformIO внутри atomically также опасно, но по другим причинам. См. unsafeIOToSTM для получения более подробной информации об этом.

retry :: STM a Исходный код

Повторить выполнение текущей памяти транзакции, потому что она обнаружила значения в TVars, которые означают, что выполнение не должно продолжаться (например, TVars представляют собой общий буфер, который теперь пуст). Реализация может заблокировать поток до тех пор, пока один из TVars, который она прочитала, не будет обновлен. (Только GHC)

orElse :: STM a -> STM a -> STM a Исходный код

Композиция двух альтернативных действий STM (только GHC).

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

throwSTM :: Exception e => e -> STM a Исходный код

Вариант throw, который может быть использован только внутри монады STM.

Выбрасывание исключения в STM прерывает транзакцию и распространяет исключение. Если исключение перехвачено с помощью catchSTM, только изменения, заключенные в блок перехвата, отменяются; изменения, сделанные вне catchSTM, сохраняются.

Если исключение не перехвачено внутри STM, оно повторно выбрасывается atomically, и вся STM отменяется.

Хотя throwSTM имеет тип, который является экземпляром типа throw, эти две функции отличаются:

throw e    `seq` x  ===> throw e
throwSTM e `seq` x  ===> x

Первый пример вызовет исключение e, а второй - нет. Фактически, throwSTM будет вызывать исключение только при использовании внутри монады STM. Вариант throwSTM должен использоваться вместо throw для поднятия исключения внутри монады STM, потому что он гарантирует порядок относительно других операций STM, в то время как throw этого не делает.

catchSTM :: Exception e => STM a -> (e -> STM a) -> STM a Исходный код

Обработка исключений внутри действий STM.

catchSTM m f перехватывает любое исключение, брошенное m с помощью throwSTM, используя функцию f для обработки исключения. Если происходит исключение, любые изменения, внесенные m, отменяются, но изменения до m сохраняются.

data TVar a Исходный код

Обменные места памяти, поддерживающие атомарные транзакции памяти.

Конструкторы

TVar (TVar# RealWorld a)
Экземпляры
Подробности экземпляров
Eq (TVar a) Исходный код

С момента: base-4.8.0.0

Подробности экземпляра

Определено в GHC.Internal.Conc.Sync

Методы

(==) :: TVar a -> TVar a -> Bool Исходный код

(/=) :: TVar a -> TVar a -> Bool Исходный код

newTVar :: a -> STM (TVar a) Исходный код

Создать новую TVar, содержащую предоставленное значение

newTVarIO :: a -> IO (TVar a) Исходный код

Вариант IO newTVar. Это полезно для создания TVar верхнего уровня с помощью unsafePerformIO, поскольку использование atomically внутри unsafePerformIO невозможно.

readTVar :: TVar a -> STM a Исходный код

Возвращает текущее значение, хранящееся в TVar.

readTVarIO :: TVar a -> IO a Исходный код

Возвращает текущее значение, хранящееся в TVar. Это эквивалентно

 readTVarIO = atomically . readTVar

но работает намного быстрее, так как не выполняет полную транзакцию, а просто считывает текущее значение TVar.

writeTVar :: TVar a -> a -> STM () Исходный код

Записать предоставленное значение в TVar.

unsafeIOToSTM :: IO a -> STM a Source

Опасно выполняет IO в STM монаде. Осторожно: это очень опасно.

  • Реализация STM часто будет запускать транзакции несколько раз, поэтому вам нужно быть готовым к этому, если ваша IO имеет побочные эффекты.
  • Реализация STM будет прерывать транзакции, которые, как известно, недействительны и требуют перезапуска. Это может произойти в середине unsafeIOToSTM, поэтому убедитесь, что вы не получаете никаких ресурсов, требующих освобождения (обработчики исключений игнорируются при прерывании транзакции). Это включает в себя выполнение любой IO с использованием дескрипторов файлов, например. Неправильное выполнение этой операции, вероятно, приведёт к случайным тупикам.
  • Транзакция может увидеть несогласованное состояние памяти, когда выполняется IO. Инварианты, которые вы ожидаете, будут истинными на протяжении всего вашего приложения, могут быть ложными внутри транзакции из-за способа реализации транзакций. Обычно это не было бы заметно программисту, но использование unsafeIOToSTM может это продемонстрировать.

Разное

withMVar :: MVar a -> (a -> IO b) -> IO b Source

Предоставьте действие IO с текущим значением MVar. MVar будет пустым в течение времени, пока выполняется действие.

type Signal = CInt Source

type HandlerFun = ForeignPtr Word8 -> IO () Source

setHandler :: Signal -> Maybe (HandlerFun, Dynamic) -> IO (Maybe (HandlerFun, Dynamic)) Source

runHandlers :: ForeignPtr Word8 -> Signal -> IO () Source

ensureIOManagerIsRunning :: IO () Source

ioManagerCapabilitiesChanged :: IO () Source

setUncaughtExceptionHandler :: (SomeException -> IO ()) -> IO () Source

getUncaughtExceptionHandler :: IO (SomeException -> IO ()) Source

reportError :: SomeException -> IO () Source

reportStackOverflow :: IO () Source

reportHeapOverflow :: IO () Source

© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/9.12.1/docs/libraries/base-4.21.0.0-8e62/GHC-Conc.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API