Spec-Zone.ru › Haskell 7

GHC.Conc.Sync

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

Содержание

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

Описание

Основные средства параллелизма.

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. Надеемся, что этот недостаток будет исправлен позже.

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

ThreadId ThreadId#

Экземпляры

Eq ThreadId
Ord ThreadId
Show ThreadId

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

forkIO :: IO () -> IO ThreadId Source

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

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

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

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

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

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

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

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

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

С версии: 4.4.0.0

forkOn :: Int -> IO () -> IO ThreadId Source

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

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

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

С версии: 4.4.0.0

forkOnWithUnmask :: Int -> ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId Source

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

С версии: 4.4.0.0

numCapabilities :: Int Source

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

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

getNumCapabilities :: IO Int Source

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

С версии: 4.4.0.0

setNumCapabilities :: Int -> IO () Source

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

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

С версии: 4.5.0.0

getNumProcessors :: IO Int Source

Возвращает количество процессоров, которыми обладает машина

С версии: 4.5.0.0

numSparks :: IO Int Source

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

childHandler :: SomeException -> IO () Source

myThreadId :: IO ThreadId Source

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

killThread :: ThreadId -> IO () Source

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

killThread tid = throwTo tid ThreadKilled

throwTo :: Exception e => ThreadId -> e -> IO () Source

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 Source

pseq :: a -> b -> b infixr 0 Source

runSparks :: IO () Source

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

yield :: IO () Source

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

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

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

Другие приложения, такие как графический отладчик Concurrent Haskell (http://www.informatik.uni-kiel.de/~fhu/chd/), могут также выбрать перегрузку labelThread для своих целей.

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

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

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

Since: 4.6.0.0

data ThreadStatus Source

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

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

ThreadRunning

поток в данный момент готов к запуску или запущен

ThreadFinished

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

ThreadBlocked BlockReason

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

ThreadDied

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

Типы

Eq ThreadStatus
Ord ThreadStatus
Show ThreadStatus

data BlockReason Source

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

BlockedOnMVar

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

BlockedOnBlackHole

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

BlockedOnException

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

BlockedOnSTM

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

BlockedOnForeignCall

в данный момент выполняет вызов внешней функции

BlockedOnOther

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

Типы

Eq BlockReason
Ord BlockReason
Show BlockReason

threadStatus :: ThreadId -> IO ThreadStatus Source

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

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

С момента: 4.4.0.0

Счётчик и квота выделения

setAllocationCounter :: Int64 -> IO () Источник

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

С этим счётчиком можно сделать две вещи:

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

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

С момента: 4.8.0.0

getAllocationCounter :: IO Int64 Источник

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

С момента: 4.8.0.0

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

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

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

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

С момента: 4.8.0.0

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

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

С момента: 4.8.0.0

TVars

newtype STM a Источник

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

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

STM (State# RealWorld -> (#State# RealWorld, a#))

Примеры использования

Monad STM
Functor STM
Applicative STM
MonadPlus STM
Alternative STM

atomically :: STM a -> IO a Источник

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

Вы не можете использовать atomically внутри unsafePerformIO или unsafeInterleaveIO. Любая попытка сделать это приведёт к ошибке во время выполнения. (Причина: это позволило бы создать транзакцию внутри транзакции, в зависимости от того, когда именно будет вычисляться ленивая запись.)

Однако, см. newTVarIO, который может быть вызван внутри unsafePerformIO, и который позволяет выделять TVars верхнего уровня.

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 прерывает транзакцию и распространяет исключение.

Хотя 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.

alwaysSucceeds :: STM a -> STM () Источник

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

always :: STM Bool -> STM () Источник

always — это вариант alwaysSucceeds, в котором инвариант выражается как действие STM Bool, которое должно возвращать True. Возврат False или вызов исключения интерпретируются как нарушения инварианта.

data TVar a Источник

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

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

TVar (TVar# RealWorld a)

Примеры использования

Eq (TVar a)

newTVar :: a -> STM (TVar a) Источник

Создаёт новый TVar, содержащий предоставленное значение

newTVarIO :: a -> IO (TVar a) Source

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

readTVar :: TVar a -> STM a Source

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

readTVarIO :: TVar a -> IO a Source

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

 readTVarIO = atomically . readTVar

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

writeTVar :: TVar a -> a -> STM () Source

Записывает указанное значение в 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

modifyMVar_ :: MVar a -> (a -> IO a) -> IO () Source

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

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

reportError :: SomeException -> IO () Source

reportStackOverflow :: IO () Source

sharedCAF :: a -> (Ptr a -> IO (Ptr a)) -> IO a Source

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

Spec-Zone.ru

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