Transcript
Programación Concurrente y Tiempo Real Tema 3. Paso de Mensajes Escuela Superior de Informática Universidad de Castilla-La Mancha
Curso 2011/2012
Grado en Ing. Informática
Tema 3. Paso de Mensajes 1. Conceptos básicos [Stallings 5.5] 2. Implementación [Rochk 7.4, 7.7] 3. Problemas clásicos de sincronización
Curso 2011/2012
Grado en Ing. Informática
Conceptos | Implementación | Problemas
Fundamentos básicos
Info a compartir
Espacio de direcciones de p0
Curso 2011/2012
Mensaje
Mecanismo de comunicación entre procesos (IPC) del sistema operativo
Copia de info
Espacio de direcciones de p1
Trp 3 de 25
Conceptos | Implementación | Problemas
Fundamentos básicos ●
Concepto de cola o buzón de mensajes
Proceso1
send ()
Message Message Mensaje
receive ()
Proceso2
Cola de mensajes
Curso 2011/2012
Trp 4 de 25
Conceptos | Implementación | Problemas
Fundamentos básicos Proceso 1
Proceso 2
while (1) { // W_previo_1 send ('*', P2) // W_restante_1 }
while (1) { // W_previo_2 receive (&msg, P1) // W_restante_2 }
Sincronización (P2 no avanza hasta que no recibe de P1)
Curso 2011/2012
Trp 5 de 25
Conceptos | Implementación | Problemas
Fundamentos básicos Aspectos de diseño en el paso de mensajes
Sincronización
Receive
Send Bloqueante ●No bloq. ●
Bloqueante ●No bloq. ●Comprob. llegada ●
Curso 2011/2012
Direccionamiento
Directo Send ●Receive ●
Indirecto Estático ●Dinámico ●Propiedad ●
Formato
Contenido
Disciplina de cola
Longitud ● ●
FIFO
Prioridad
Fija Variable
Trp 6 de 25
Conceptos | Implementación | Problemas
El problema de la sección crítica do { SECCIÓN_ENTRADA SECCIÓN_CRÍTICA SECCIÓN_SALIDA SECCIÓN_RESTANTE
while(1);
Curso 2011/2012
Trp 7 de 25
Conceptos | Implementación | Problemas
El problema de la sección crítica do { receive (buzón, &msg) SECCIÓN_CRÍTICA send (buzón, msg) SECCIÓN_RESTANTE
while(1);
Curso 2011/2012
¡La cola de mensajes actúa de semáforo! Mutex ~ Cola 1 msg Semáforo contador ~ Cola n msg
Trp 8 de 25
Conceptos | Implementación | Problemas
POSIX Message Queues Apertura de una cola de mensajes #include #include #include
// Para constantes O_*. // Para los permisos.
// Devuelve el descriptor de la cola de mensajes // o -1 si hubo error (ver errno). mqd_t mq_open ( const char *name, // Nombre de la cola. int oflag // Flags (menos O_CREAT). ); mqd_t mq_open ( const char *name, int oflag mode_t perms, struct mq_attr *attr );
Curso 2011/2012
// // // //
Nombre de la cola. Flags (incluyendo O_CREAT). Permisos. Atributos (o NULL).
Trp 9 de 25
Conceptos | Implementación | Problemas
POSIX Message Queues Ejemplo de creación // Descriptor de cola de mensajes. mqd_t qHandler; int rc; struct mq_attr mqAttr; // Estructura de atributos. mqAttr.mq_maxmsg = 10; // Máximo nº de mensajes. mqAttr.mq_msgsize = 1024; // Tamaño máximo de mensaje. // Creación del buzón. qHandler = mq_open(“/prueba”, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, &mqAttr); // Manejo de errores. if (qHandler == -1) { fprintf(stderr, "%s\n", strerror(errno)); exit(EXIT_FAILURE); }
Curso 2011/2012
Trp 10 de 25
Conceptos | Implementación | Problemas
POSIX Message Queues Cierre de la cola de mensajes #include int mq_close ( mqd_t mqdes );
// Descriptor de la cola de mensajes.
Eliminación de la cola de mensajes #include int mq_unlink ( const char *name );
Curso 2011/2012
// Nombre de la cola.
Trp 11 de 25
Conceptos | Implementación | Problemas
POSIX Message Queues Envío / recepción de mensajes #include int mq_send ( mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio );
// // // //
Descriptor de la cola. Mensaje. Tamaño del mensaje. Prioridad.
ssize_t mq_receive ( mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio );
// // // //
Descriptor de la cola. Buffer para el mensaje. Tamaño del buffer. Prioridad o NULL.
Curso 2011/2012
Trp 12 de 25
Conceptos | Implementación | Problemas
Recibiendo mensajes... Ejemplo de recepción bloqueante mqd_t qHandler; int rc; unsigned int prioridad; char buffer[2048]; rc = mq_receive(qHandler, buffer, sizeof(buffer), &prioridad); if (rc == -1) fprintf(stderr, "%s\n", strerror(errno)); else printf ("Recibiendo mensaje: %s\n", buffer);
¡El buffer de recepción ha de ser mayor o igual a mq_msgsize!
Curso 2011/2012
Trp 13 de 25
Conceptos | Implementación | Problemas
Enviando mensajes... Ejemplo de envío [no] bloqueante mqd_t qHandler; int rc; unsigned int prioridad; char buffer[512]; sprintf (buffer, "[ Saludos de %d ]", getpid()); mq_send(qHandler, buffer, sizeof(buffer), 1);
¡El buffer de envío ha de ser menor o igual a mq_msgsize!
Curso 2011/2012
Trp 14 de 25
Conceptos | Implementación | Problemas
Custom messages ●
Muchos APIs utilizan char* como buffer genérico... ¡Considera un puntero a un buffer junto con el tamaño del buffer para usar tus TADs!
Curso 2011/2012
Trp 15 de 25
Conceptos | Implementación | Problemas
Custom messages Ejemplo de uso de custom data typedef struct { int valor; } TData; TData buffer; // Atributos del buzón. mqAttr.mq_maxmsg = 10; mqAttr.mq_msgsize = sizeof(TData); // Recepción. mq_receive(qHandler, (char *)&buffer, sizeof(buffer), &prioridad); // Envío. mq_send(qHandler, (const char *)&buffer, sizeof(buffer), 1);
Curso 2011/2012
Trp 16 de 25
Conceptos | Implementación | Problemas
POSIX Message Queues Notificación de mensajes #include int mq_notify ( // Descriptor de la cola. mqd_t mqdes, // Estructura de notificación. // Contiene funciones de retrollamada // para notificar la llegada de un nuevo mensaje. const struct sigevent *sevp );
Curso 2011/2012
Trp 17 de 25
Conceptos | Implementación | Problemas
El problema del bloqueo ●
●
Con POSIX Message Queues, no es posible recuperar mensajes por tipo ¿Cómo atender distintas peticiones (tipos de tareas) de manera eficiente? ●
Sin bloquearse en una cola...
●
Ver qt_notify ()
●
Ver [Roch 5.18]
Curso 2011/2012
Trp 18 de 25
Conceptos | Implementación | Problemas
Esquema beeper ●
Procesos bloqueados (receive ()) a la espera de una tarea (mensaje)
1
Proceso1
Curso 2011/2012
re
e ceiv
()
receive ()
Buzón Beeper
Proceso2
r ec e iv e ()
Proceso3
Trp 19 de 25
Conceptos | Implementación | Problemas
Esquema beeper
receive ()
¡Garantiza no bloqueo!
Buzón Beeper
r ec
eiv
e ()
Proceso2
Proceso1
Proceso3
2 receive ()
Buzón A
Curso 2011/2012
Buzón B
Trp 20 de 25
Conceptos | Implementación | Problemas
Productor/Consumidor while (1) { // Producir... producir(); // Nuevo item... send (buzón, msg); }
Se bloquea si la cola está llena
Curso 2011/2012
Se bloquea si no hay elementos (mensajes)
while (1) { recibir (buzón, &msg) // Consumir... consumir(); }
Trp 21 de 25
Conceptos | Implementación | Problemas
Filósofos comensales
Proceso filósofo while (1) { // Pensar... wait(palillos[i]); wait(palillos[(i+1) % 5]); // Comer... signal(palillos[i]); signal(palillos[(i+1) % 5]); }
Curso 2011/2012
Trp 22 de 25
Conceptos | Implementación | Problemas
Filósofos comensales Proceso filósofo while (1) { // Pensar... receive(mesa, &m); receive(palillo[i], &m); receive(palillo[i+1], &m); // Comer... send(palillo[i], m); send(palillo[i+1], m); send(mesa, m); }
Curso 2011/2012
Trp 23 de 25
Conceptos | Implementación | Problemas
Los fumadores de cigarrillos
Tabaco Papel Fósforos
Agente
Curso 2011/2012
Tabaco
Papel
Fósforos
Fumador1
Fumador2
Fumador3
Tabaco
Papel
Trp 24 de 25
Conceptos | Implementación | Problemas
Traducción de cadenas ●
Sesión 4 Laboratorio
Curso 2011/2012
Trp 25 de 25