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ó
forkIO
pren una accióIO
i 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: " ++ value
Explicació
newEmptyMVar
crea unMVar
buit.putMVar
posa un valor en elMVar
.takeMVar
llegeix 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 a
Explicació
async
crea una acció asíncrona.wait
espera 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 value
Explicació
atomically
executa una transacció STM.newTVar
,writeTVar
ireadTVar
só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 finishes
Exercici 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: " ++ value
Resum
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.