La concurrència és un concepte clau en la programació moderna, especialment en llenguatges com Haskell, que ofereixen eines poderoses per gestionar múltiples tasques simultànies. En aquest tema, explorarem com Haskell maneja la concurrència, incloent-hi les primitives bàsiques, les biblioteques i els patrons comuns.
Objectius del Tema
- Entendre els conceptes bàsics de la concurrència.
- Aprendre a utilitzar les primitives de concurrència en Haskell.
- Explorar les biblioteques de concurrència més utilitzades.
- Implementar exemples pràctics de programes concurrents.
Conceptes Bàsics de Concurrència
Què és la Concurrència?
La concurrència és la capacitat d'un programa per executar múltiples tasques al mateix temps. Això pot millorar l'eficiència i la capacitat de resposta d'un programa, especialment en sistemes amb múltiples nuclis de CPU.
Concurrència vs Paral·lelisme
- Concurrència: Es refereix a la descomposició d'un programa en parts que poden ser executades de manera independent. No implica necessàriament que aquestes parts s'executin simultàniament.
- Paral·lelisme: Es refereix a l'execució simultània de múltiples tasques en diferents nuclis de CPU.
Primitives de Concurrència en Haskell
forkIO
La funció forkIO és una de les primitives més bàsiques per crear un nou fil d'execució (thread) en Haskell.
import Control.Concurrent
main :: IO ()
main = do
forkIO $ putStrLn "Hello from the new thread!"
putStrLn "Hello from the main thread!"Explicació
forkIOpren una accióIOi la executa en un nou fil d'execució.- En l'exemple anterior, el missatge "Hello from the new thread!" es pot imprimir abans o després del missatge "Hello from the main thread!", depenent de l'ordre d'execució dels fils.
MVar
MVar és una variable mutable que pot ser utilitzada per compartir dades entre fils de manera segura.
import Control.Concurrent
import Control.Concurrent.MVar
main :: IO ()
main = do
mvar <- newEmptyMVar
forkIO $ do
putStrLn "Child thread: Putting value into MVar"
putMVar mvar "Hello from MVar"
value <- takeMVar mvar
putStrLn $ "Main thread: Got value from MVar: " ++ valueExplicació
newEmptyMVarcrea unMVarbuit.putMVarposa un valor en elMVar.takeMVarllegeix i elimina el valor delMVar.
Biblioteques de Concurrència
async
La biblioteca async proporciona una interfície més alta per treballar amb concurrència.
import Control.Concurrent.Async
main :: IO ()
main = do
a <- async $ do
threadDelay 1000000
putStrLn "Hello from async"
putStrLn "Hello from main"
wait aExplicació
asynccrea una acció asíncrona.waitespera que l'acció asíncrona acabi.
STM (Software Transactional Memory)
STM és una altra eina poderosa per gestionar la concurrència en Haskell.
import Control.Concurrent.STM
main :: IO ()
main = do
tv <- atomically $ newTVar 0
atomically $ writeTVar tv 42
value <- atomically $ readTVar tv
putStrLn $ "Value: " ++ show valueExplicació
atomicallyexecuta una transacció STM.newTVar,writeTVarireadTVarsón operacions sobre variables transaccionals.
Exercicis Pràctics
Exercici 1: Crear un Fil d'Execució
Crea un programa que utilitzi forkIO per crear un nou fil d'execució que imprimeixi un missatge després d'un retard de 2 segons.
Solució
import Control.Concurrent
main :: IO ()
main = do
forkIO $ do
threadDelay 2000000
putStrLn "Hello from the new thread after 2 seconds!"
putStrLn "Hello from the main thread!"
threadDelay 3000000 -- Wait to ensure the new thread finishesExercici 2: Utilitzar MVar per Compartir Dades
Crea un programa que utilitzi MVar per compartir un valor entre dos fils d'execució.
Solució
import Control.Concurrent
import Control.Concurrent.MVar
main :: IO ()
main = do
mvar <- newEmptyMVar
forkIO $ do
putStrLn "Child thread: Putting value into MVar"
putMVar mvar "Hello from MVar"
value <- takeMVar mvar
putStrLn $ "Main thread: Got value from MVar: " ++ valueResum
En aquest tema, hem explorat els conceptes bàsics de la concurrència en Haskell, incloent-hi les primitives bàsiques com forkIO i MVar, així com biblioteques més avançades com async i STM. Hem vist exemples pràctics i hem proporcionat exercicis per reforçar els conceptes apresos. La concurrència és una eina poderosa que pot millorar significativament l'eficiència i la capacitat de resposta dels programes Haskell.
