El pas de missatges[1] en ciències de la computació és un paradigma de programació utilitzat com a alternativa al model de memòria compartida, sent aquest últim difícil o impossible de traslladar a sistemes distribuïts, on no existeix físicament la memòria compartida. Les seves aplicacions són diverses, i pot utilitzar-se des de per garantir que els diferents objectes que constitueixen un programa informàtic puguin treballar de forma coherent entre ells, fins a permetre que una tasca es pugui executar de forma sincronitzada entre varis ordinadors. Per tal de poder implementar el pas de missatges, entre els processos que es comuniquen ha de existir un enllaç de comunicació.
El model de pas de missatges és el que defineix els mètodes i funcions per a poder portar a terme l'enviament d'un missatge d'un procés emissor a un destinatari. Suposa un enfocament oposat al paradigma tradicional en el qual els processos, funcions i subrutines només poden ser cridats directament a través del seu nom. Consta de dos primitives bàsiques: send (destí, missatge) i recive (origen, missatge).
Introducció
El pas de missatges és una tècnica que s'utilitza per a, des d'un procés, invocar de forma abstracta un comportament concret per part d'un altre actor (per exemple, executar una funció o un programa). Això suposa un gran canvi respecte al model tradicional on es cridava als programes i funcions només pel seu nom, el pas de missatges constitueix un mecanisme essencial per a distingir una funció de la seva implementació interna (el destinatari al rebre el missatge, decidirà l'acció que ha d'executar per a complir la petició).[2]
Entre els avantatges que proporciona aquest mecanisme trobem el alt grau de compatibilitat, ja que pot ser vàlid per a qualsevol tipus d'arquitectura de computadors, ja siguin sistemes distribuïts, arquitectures paral·leles sense memòria compartida i també amb sistemes de memòria compartida i, per altra banda, no existeix el problema de l'accés en exclusió mútua a dades compartides.
Cas práctic en programació orientada a objectes
Un exemple clàssic de aplicació del model de pas de missatges pot ser en l'àmbit de la informàtica gràfica. Per exemple, si el programador està creant un programa que treballa amb diversos tipus de formes geomètriques de una classe Forma, el programa contindrà varis objectes instàncies de la classe mencionada, com per exemple un quadrat, un rombe o triangle.
Imaginem el cas en què el programador desitja conèixer l'àrea dels objectes de la classe Forma declarats. Com el càlcul de les àrees de les formes no és el mateix per a totes, en un model tradicional el programador es veuria obligat a crear una estructura condicional IF-ELSE que consultés el tipus de forma que és per a executar l'operació matemàtica corresponent.
En lloc d'això, el model de pas de missatges només necessita enviar un missatge a cada objecte consultant l'àrea. Seria la implementació interna de la classe Forma la que s'encarregaria de escollir i calcular la forma correcta. El objecte, respondria a la petició enviant un altre missatge al destinatari amb el àrea resultant del càlcul. Com es natural, per que això sigui possible, la classe destinatària ha de tenir implementat prèviament el mètode per a poder interpretar els missatges de forma normalitzada, així com les funcions necessàries per a realitzar el càlcul de l'àrea.
Característiques canals de comunicació
Segons les característiques del canal de comunicació o enllaç utilitzat entre processos es poden distingir els següents aspectes:
Tipus de comunicació
Comunicació directa: S'estableix automàticament la comunicació i únicament s'associen dos processos al canal. El tipus d'enllaç pot ser unidireccional o bidireccional.
Comunicació indirecta: S'estableix un canal entre dos processos únicament si tenen una cua de missatges compartida (bústia), permetent que entre un parell de processos de comunicació puguin haver varis enllaços diferents. El tipus d'enllaç pot ser unidireccional o bidireccional.[1]
Seguretat
Un concepte fonamental relacionat amb la diferència entre el pas síncron i asíncron és la seguretat del pas del missatge. El pas del missatge és segur quan podem garantir que el missatge que rep el destinatària és el mateix que envia el emissor i que no s'ha produït ninguna alteració en el contingut del missatge durant el temps que transcorre entre el enviament i la recepció. El enviament síncron sempre es segur, en canvi, el asíncron no es segur, pel que és el programador qui s'ha d'encarregar de garantir la seguretat del missatge.
Cardinalitat dels esquemes de comunicació
(1:1): Cada canal té un emissor i un receptor.
(N:1): N processos poden enviar missatges pel canal i només un pot rebre'ls (habitualment anomenat com a port).
(N:N): Varis emissors i varis receptor. Poc utilitzat.
La recepció i enviament en el pas de missatges poden estar definides com a bloquejant o no bloquejant, és a dir, el procés que envia/rep el missatge continuará o no segons aquest comportament. Segons aquesta necessitat o no de sincronització es distingeixen:
Síncron
Enviament/recepció bloquejant, emissor i receptor es sincronitzen per intercanviar cada missatge (Analogia: parlar per telèfon amb una persona). El pas de missatge síncron sempre es segur, ja que es pot garantir que no hi ha possibilitat que el missatge pugui ser modificat en el pas del temps. Aquest és fàcil de implementar però es poc flexible, ja que els dos processos han d'esperar fins a estar en el mateix punt del seu codi per a poder comunicar el missatge, evitant que es pugui garantir que el temps que passa entre que el emissor executi la instrucció send() fins que el receptor executi la instrucció receive() sigui raonable, podent perjudicar al rendiment dels dos processos. Una mala programació pot arribar a que un procés executi una funció d'enviament i que no tingui la seva corresponent funció de recepció o viceversa, podent quedar bloquejats indefinidament esperant l'un a l'altre (deadlock).
Asíncron
Enviament/recepció no bloquejant, l'emissor continua executant-se sense esperar a que la comunicació tingui efecte (Analogia: E-mail, telegrames...). Que l'emissor no quedi bloquejat després d'enviar el missatge és una avantatge respecte a l'eficiència general del sistema, però pot portar riscos de seguretat en el pas del missatge, podent modificar variables enviades en un instant de temps abans que el receptor llegeixi el valor correcte (consistència). En general, aquest comportament permet major grau de concurrència, però necessita d'implementacions de cues de missatges o buffer.
Enviament asíncron fiable
Habitualment, els estàndards inclouen un mecanisme de pas de missatges que, encara que sent asíncron, garanteixen la fiabilitat de l'enviament. D'aquesta manera l'emissor executa la funció corresponent (send()), còpia les dades en un lloc segur per evitar que aquestes es puguin modificar, i a continuació continua la seva execució amb normalitat. En el moment que el procés receptor executa la seva ordre per a rebre el missatge amb la primitiva (receive()), rebrà les dades que l'emissor va copiar inicialment en un lloc fiable, de manera que això garanteix que les dades no han estat modificades durant l'interval de temps transcorregut.
Enviament asíncron no fiable
A part de les funcions d'enviament asíncron fiable, les interfícies de pas de missatges també solen incorporar funcions que permeten passar missatges de forma no fiable. En aquest cas, el procés emissor executarà l'ordre d'enviament insegur (i_send()), es donarà l'ordre d'enviament i instantàniament es retornarà el control al programa principal, sense esperar que els bytes hagin acabat de ser llegits en l'emissor ni escrits en el receptor. Per la seva part, el receptor executarà l'ordre de recepció no fiable (i_receive()), de manera que es donarà l'ordre de recepció i a continuació es retornarà el control del programa, sense esperar que es completi l'enviament ni que acabin d'arribar les dades.
En aquest cas, el responsable de garantir manualment la integritat del missatge és el programador. Les interfícies de pas de missatges incorporen una sèrie de funcions que permeten al programador sondejar l'estat del missatge i actuar en conseqüència. Concretament, es disposa de funcions de sondeig bloquejant (wait_send() i wait_recv()), les quals bloquegen l'emissor i receptor respectivament si l'enviament o recepció del missatge encara no ha finalitzat. El programador també disposa de funcions de sondeig no bloquejant (test_send() i test_recv()) que permeten conèixer aquesta mateixa informació sense bloquejar cap procés, simplement retornant un valor booleà perquè sigui el programador el que decideixi l'acció a prendre en cada cas.
Referències
↑ 1,01,1«Paso de mensajes» (en castellà). germantp, 25-04-2017. [Consulta: 10 febrer 2017].
↑ 2,02,1S. Tanenbaum, Andrew. Sistemas Operativos Distribuidos. (en castellà). PRENTICE HALL HISPANOAMERICANA S.A. ISBN 9789688806272.