En ciències de la computació, els cadenats d'exclusió mútua o «locks» (anglès) són un mecanisme de sincronització que limita l'accés a un recurs compartit per diversos processos o fils en un ambient d'execució concurrent, permetent així l'exclusió mútua.
Quan un element és compartit per més d'un fil, poden ocórrer condicions de competició si aquest no és protegit adequadament. El mecanisme més simple per a la protecció és el cadenat o tanca. En general quan ha de protegir un conjunt d'elements, se li associa un cadenat. Cada procés/fil per a tenir accés a un element del conjunt, haurà de bloquejar, de manera que es converteix en el seu amo. Aquesta és l'única forma de guanyar accés. En acabar d'usar-lo, el propietari ha de desbloquejar, per permetre que un altre procés/fil pugui prendre al seu torn. És possible que mentre un procés/fil estigui accedint a un recurs (sent per tant propietari del cadenat), un altre procés/fil intenti accedir. Aquesta acció ha d'esperar fins que el cadenat es trobi lliure, per garantir l'exclusió mútua. El procés/fil sol·licitant queda llavors en espera o passa a estat de bloqueig segons l'algorisme implementat. Quan el propietari del cadenat el desbloqueja pot prendre'l algun dels processos/fils que esperaven.
Aquest mecanisme es pot veure en un exemple de la vida real. Suposem un lavabo públic, on només pot entrar una persona a la vegada. Un cop dins, s'empra un cadenat per evitar que entrin altres persones. Si una altra persona pretén fer servir el lavabo quan està ocupat, haurà de quedar esperant que la persona que va entrar abans acabi. Si més persones arribessin, formarien una cua (del tipus FIFO) i esperarien el seu torn. En informàtica, el programador no ha d'assumir aquest tipus de comportament a la cua d'espera.
El cadenat, usat d'aquesta manera, forma una secció crítica En cada procés/fil, des que és pres fins que s'allibera. En l'exemple del lavabo, dins de la secció crítica es troben les funcions que es realitzen generalment dins d'aquest tipus d'instal·lacions sanitàries. Com garanteixen l'exclusió mútua, moltes vegades se'ls anomena mutex (per mutual exclusion).
En general hi ha un nombre de restriccions sobre els cadenats, encara que no són les mateixes en tots els sistemes. Aquestes són: Només el propietari d'un cadenat pot desbloquejar La readquisició d'un cadenat no està permesa
Una cosa molt important és que tots els processos/fils han d'utilitzar el mateix protocol per bloquejar i desbloquejar els cadenats en l'accés als recursos, ja que si mentre dos processos/fils utilitzen el cadenat de forma correcta, hi ha un altre que simplement accedeix a les dades protegits, no es garanteix l'exclusió mútua i poden donar-se condicions de competició i errors en els resultats.
Primitives i ús Les funcions dels cadenats en general són tres: init () , lock () i unlock () . El cadenat s'inicialitza amb la funció init () . Després cada procés/fil ha de cridar a la funció lock () abans d'accedir a les dades protegides pel cadenat. En finalitzar la seva secció crítica, el propietari del cadenat ha de desbloquejar-lo mitjançant la funció unlock () .
Ús en programació concurrent En programació concurrent, els cadenats s'utilitzen per protegir seccions crítiques, és a dir, fragments de codi en què s'accedeix a un recurs compartit. Aquest recurs pot ser una variable, una estructura de dades, un fitxer, una connexió de xarxa o qualsevol altre element que pugui ser llegit o modificat per més d'un fil o procés. Quan un fil adquireix el cadenat, la resta de fils que volen accedir al mateix recurs han d'esperar fins que aquest sigui alliberat. Això evita que dues operacions incompatibles es facin al mateix temps i ajuda a mantenir la coherència de les dades.
En moltes biblioteques de programació, un cadenat té dues operacions bàsiques: adquirir-lo i alliberar-lo. A Python, per exemple, un objecte Lock pot estar en estat bloquejat o desbloquejat; el mètode acquire() intenta obtenir el cadenat i el mètode release() l'allibera quan la secció crítica ja ha acabat. Si un fil intenta adquirir un cadenat que ja és bloquejat, queda en espera fins que un altre fil l'allibera.
Cadenats reentrants Un cadenat reentrant és un tipus de cadenat que pot ser adquirit més d'una vegada pel mateix fil sense que aquest quedi bloquejat per ell mateix. Aquest comportament pot ser útil quan una funció que ja ha adquirit un cadenat crida una altra funció que també necessita protegir el mateix recurs. En aquest cas, el cadenat manté un recompte intern de les adquisicions i només queda realment alliberat quan el fil l'ha alliberat el mateix nombre de vegades que l'ha adquirit.
Problemes habituals Tot i que els cadenats són una eina bàsica de sincronització, un ús incorrecte pot provocar problemes de rendiment o de correcció. Si una secció crítica és massa llarga, altres fils poden passar massa temps esperant i es pot reduir el paral·lelisme efectiu del programa. També pot aparèixer un interbloqueig quan dos o més fils mantenen cadenats diferents i cadascun espera que l'altre alliberi el recurs que necessita per continuar.
Per reduir aquests riscos, és habitual mantenir les seccions crítiques tan curtes com sigui possible, alliberar sempre els cadenats després d'utilitzar-los i adquirir diversos cadenats en un ordre coherent. En alguns llenguatges i biblioteques també es recomana utilitzar mecanismes que alliberin automàticament el cadenat en sortir del bloc protegit, per evitar que una excepció o un retorn prematur deixi el recurs bloquejat.
Referències
Vegeu també Monitor (concurrència) Teoria de cues
Categoria:Programació Categoria:Sistemes operatius Categoria:Terminologia informàtica