~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 322286BD0D4669796EE7303DD57DA3C6__1703256360 ✰
Заголовок документа оригинал.:
✰ Concurrent Haskell - Wikipedia ✰
Заголовок документа перевод.:
✰ Параллельный Haskell — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Concurrent_Haskell ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/32/c6/322286bd0d4669796ee7303dd57da3c6.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/32/c6/322286bd0d4669796ee7303dd57da3c6__translat.html ✰
Дата и время сохранения документа:
✰ 22.06.2024 17:06:42 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 22 December 2023, at 17:46 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Параллельный Haskell — Википедия Jump to content

Параллельный Haskell

Из Википедии, бесплатной энциклопедии

Параллельное расширение Haskell [1] Haskell 98 с явным параллелизмом . Две основные концепции, лежащие в его основе, таковы:

  • Примитивный тип MVar α реализация ограниченного/одноместного асинхронного канала , который либо пуст, либо содержит значение типа α.
  • Возможность создания параллельного потока через forkIO примитивный.

На основе этого создан набор полезных абстракций параллелизма и синхронизации. [2] такие как неограниченные каналы , семафоры и выборочные переменные.

Потоки Haskell имеют очень низкие накладные расходы: создание, переключение контекста и планирование являются внутренними для среды выполнения Haskell. Эти потоки уровня Haskell отображаются в настраиваемое количество потоков уровня ОС, обычно по одному на каждое ядро ​​процессора .

транзакционная память Программная

Расширение программной транзакционной памяти (STM) [3] в GHC повторно использует примитивы процесса разветвления Concurrent Haskell. СТМ однако:

STM-монада [ править ]

СТМ- монада [4] — это реализация программной транзакционной памяти в Haskell. Он реализован в GHC и позволяет изменять изменяемые переменные в транзакциях .

Традиционный подход [ править ]

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

type   Account   =   IORef   Целочисленная 

 передача   ::   Integer   ->   Account   ->   Account   ->   IO   () 
 перевода   сумма   от   to   =   do 
     fromVal   <-   readIORef   from    -- (A) 
     toVal     <-   readIORef   to 
     writeIORef   from   (  fromVal   -   количество  ) 
     writeIORef   to   (  toVal   +   сумма  ) 

осуществляться несколько переводов Это вызывает проблемы в одновременных ситуациях, когда на одном и том же счете одновременно может . Если было два перевода денег со счета from, и оба вызова для передачи пробежали строку (A) до того, как кто-либо из них запишет свои новые значения, возможно, что деньги будут переведены на два других счета, при этом только одна из переводимых сумм будет удалена со счета. from, создавая таким образом состояние гонки . Это приведет к тому, что банковское приложение окажется в несогласованном состоянии.

Традиционное решение такой проблемы – блокировка. Например, можно установить блокировки для изменений в учетной записи, чтобы обеспечить атомарное зачисление и дебетование. В Haskell блокировка осуществляется с помощью MVars:

type   Account   =   MVar   Целочисленный 

 кредит   ::   Целое   ->   Счет   ->   IO   () 
 кредита   сумма   счет   =   do 
     current   <-   takeMVar   счет 
     putMVar   счет   (  текущий   +   сумма  ) 

 дебет   ::   Целое   ->   Счет   ->   IO   () 
 дебета   сумма   счет   =   do 
     current   -   takeMVar   account 
     putMVar   account   (  текущая   сумма   )  < 

Использование таких процедур гарантирует, что деньги никогда не будут потеряны или получены из-за неправильного чередования операций чтения и записи на любой отдельный счет. Однако если попытаться объединить их вместе, чтобы создать такую ​​процедуру, как передача:

перевод   ::   Целое   ->   Счет   ->   Счет   ->   IO   () 
 перевода   сумма   от   до   =   сделать 
     дебета   сумму   от 
     кредита   суммы   до 

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

Атомарные транзакции [ править ]

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

type   Account   =   TVar   Целочисленный 

 кредит   ::   Целое   ->   Счет   ->   STM   () 
 кредита   сумма   счет   =   do 
     current   <-   readTVar   счет 
     writeTVar   счет   (  текущий   +   сумма  ) 

 дебет   ::   Целое   ->   Счет   ->   STM   () 
 дебета   сумма   счет   =   do 
     current   <-   readTVar   account 
     writeTVar   account   (  current   -   Transfer  mount) 

 ::   Integer   -   Account   -   >   Account   ->   STM   () 
 перевода   сумма   от   до   =   сумма 
     дебета   суммы   от 
     кредита   к   > 

Типы возврата STM ()может быть воспринято как указание на то, что мы составляем сценарии для транзакций. Когда приходит время фактического выполнения такой транзакции, функция atomically :: STM a -> IO aиспользуется. Вышеупомянутая реализация гарантирует, что никакие другие транзакции не мешают переменным, которые она использует (от и до) во время ее выполнения, что позволяет разработчику быть уверенным, что не возникнут условия гонки, подобные описанным выше. Можно внести дополнительные улучшения, чтобы гарантировать, что в системе поддерживается некоторая другая « бизнес-логика », то есть транзакция не должна пытаться снять деньги со счета, пока на нем не будет достаточно денег:

Transfer   ::   Integer   ->   Account   ->   Account   ->   STM   () 
 перевода   сумма   от   to   =   do 
     fromVal   <-   readTVar   from 
     if   (  fromVal   -   sum  )   >=   0 
         , затем   выполнить 
                дебет   суммы   из 
                кредита   суммы   , чтобы 
         еще раз   повторить попытку 

Здесь retryбыла использована функция, которая откатит транзакцию и повторит попытку. Повторная попытка в STM разумна, поскольку она не будет пытаться выполнить транзакцию снова, пока одна из переменных, на которые она ссылается во время транзакции, не будет изменена каким-либо другим транзакционным кодом. Это делает монаду STM весьма эффективной.

Пример программы, использующей передаточную функцию, может выглядеть так:

модуль   Main   где 

 импорт   Control.Concurrent   (  forkIO  ) 
 импорт   Control.Concurrent.STM 
 импорт   Control.Monad   (  навсегда  ) 
 импорт   System.Exit   (  exitSuccess  ) 

 тип   Account   =   TVar   Integer 

 main   =   do 
     bob   <-   newAccount   10000 
     jill   <-   newAccount   4000 
     повторитеIO   2000   $   forkIO   $   атомарно   $   трансфер   1   боб   jill 
     навсегда   $   do 
         bobBalance   <-   атомарно   $   readTVar   bob 
         jillBalance   <-   атомарно   $   readTVar   jill 
         putStrLn   (  "Баланс Боба: "   ++   show   bobBalance   ++   ", баланс Джилл: "   ++   show   jillBalance  ) 
         если   bobBalance   ==   8000 
             , то   exitSuccess 
             , иначе   putStrLn   "Повторная попытка." 

  повторитеIO   ::   Integer   ->   IO   a   ->   IO   a 
 повторитеIO   1   m   =   m 
 повторитеIO   n   m   =   m   >>   повторитеIO   (  n   -   1  )   m 

 newAccount   ::   Integer   ->   IO   Account 
 newAccount   sum   =   newTVarIO   сумма 

 перевода   ::   Integer   ->   Учетная запись   ->   Учетная запись   ->   STM   () 
 перевода   сумма   из   в   =   do 
     fromVal   <-   readTVar   from 
     if   (  fromVal   -   sum  )   >=   0 
         затем   выполнить 
                дебетование   суммы   из 
                кредита   суммы   в 
         противном случае   повторить 

 попытку кредита   ::   Integer   ->   Account   ->   STM   ( ) 
 кредита   сумма   счет   =   сделать 
     текущий   <-   readTVar   учетная запись 
     TVar   учетная запись   (  текущий   +   сумма  ) 

 дебет   ::   Integer   ->   Счет   ->   STM   () 
 дебета   сумма   учетная запись   сделать   текущий 
     <   -   readTVar   учетная запись 
     TVar   учетная запись   (  текущая   сумма   =  ) 

который должен распечатать «Баланс Боба: 8000, баланс Джилл: 6000». Здесь atomically Функция использовалась для запуска действий STM в монаде IO.

Ссылки [ править ]

  1. ^ Саймон Пейтон Джонс, Эндрю Д. Гордон и Сигбьорн Финн. Параллельный Haskell . Симпозиум ACM SIGPLAN-SIGACT по принципам языков программирования (PoPL). 1996 г. (Некоторые разделы устарели по сравнению с текущей реализацией.)
  2. ^ , Иерархические библиотеки Haskell Control.Concurrent . Архивировано 2 августа 2012 г. в archive.today.
  3. ^ Тим Харрис, Саймон Марлоу, Саймон Пейтон Джонс и Морис Херлихи . Составные транзакции с памятью . Симпозиум ACM по принципам и практике параллельного программирования 2005 г. (PPoPP'05). 2005.
  4. ^ Control.Concurrent.STM
Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 322286BD0D4669796EE7303DD57DA3C6__1703256360
URL1:https://en.wikipedia.org/wiki/Concurrent_Haskell
Заголовок, (Title) документа по адресу, URL1:
Concurrent Haskell - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)