@rachel
В Haskell многопоточность может быть реализована с помощью библиотеки Control.Concurrent. Можно создавать новые потоки с помощью функции forkIO. Например, чтобы создать новый поток, который выполняет функцию f, можно использовать следующий код:
1 2 3 4 5 6 7 |
import Control.Concurrent main :: IO () main = do forkIO f putStrLn "Main thread" -- другие действия |
Также можно использовать примитивы синхронизации, такие как MVar и STM. Например, следующий код показывает, как использовать MVar для синхронизации двух потоков:
1 2 3 4 5 6 7 8 9 10 |
import Control.Concurrent main :: IO () main = do mvar <- newEmptyMVar forkIO $ do putStrLn "Thread 1" putMVar mvar () takeMVar mvar putStrLn "Main thread" |
В этом примере, поток 1 выводит сообщение на консоль и затем помещает значение в MVar. Поток main вызывает функцию takeMVar, которая заблокируется до тех пор, пока значение не будет доступно в MVar. Когда значение будет доступно, поток main выведет сообщение на консоль.
STM (Software Transactional Memory) предоставляет более мощный механизм для синхронизации потоков в Haskell. STM позволяет описывать транзакции, которые могут быть выполнены атомарно. Пример использования STM:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import Control.Concurrent import Control.Concurrent.STM main :: IO () main = do account <- newTVarIO 100 forkIO $ atomically $ do balance <- readTVar account writeTVar account (balance - 50) putStrLn "Thread 1" forkIO $ atomically $ do balance <- readTVar account writeTVar account (balance - 75) putStrLn "Thread 2" threadDelay 1000000 -- пауза в главном потоке balance <- readTVarIO account putStrLn $ "Balance: " ++ show balance |
В этом примере создаются два потока, каждый из которых изменяет значение в TVar и выводит сообщение на консоль. Затем главный поток ожидает 1 секунду (с помощью функции threadDelay) и выводит текущий баланс, который был изменен другими потоками. Функция atomically гарантирует, что все операции с TVar выполнены атомарно.
@rachel
Этот пример демонстрирует использование примитивов многопоточности в Haskell с помощью библиотек Control.Concurrent и Control.Concurrent.STM. На примере использования forkIO для создания новых потоков и использования MVar и STM для синхронизации между потоками. Многопоточность в Haskell представляет собой мощный инструмент для параллельного и асинхронного выполнения кода.