From: Leandro Lucarella Date: Tue, 25 Apr 2006 05:24:57 +0000 (+0000) Subject: Ejercicio 2.2.2 terminado y andando. X-Git-Tag: svn_import~93 X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/commitdiff_plain/fc5c0d5eada9500c5c5e1369ef00ed201d45a3e1 Ejercicio 2.2.2 terminado y andando. --- diff --git a/practicas/practica2/P02e2221.cpp b/practicas/practica2/P02e2221.cpp new file mode 100644 index 0000000..fc6bca4 --- /dev/null +++ b/practicas/practica2/P02e2221.cpp @@ -0,0 +1,128 @@ +/** + * Leandro Lucarella (77891) + * + * Ejercicio 2.2.1. Implementa productor-consumidor con colas de mensajes, con 3 + * productores que producen 1/3 cada uno y 2 consumidores que consumen todo. + */ + +#include +#include +#include +#include +#include +#include +#include + +using std::cerr; +using std::cout; +using std::endl; + +/// Clave de nuestro segmento shm y semaforo +#define MSG_KEY 0x77891226 + +void msgbuf_init(msgbuf* m, char val, int type) +{ + m->mtype = type; + m->mtext[0] = val; +} + +void msgbuf_set_val(msgbuf* m, char val) +{ + m->mtext[0] = val; +} + +void msgbuf_set_type(msgbuf* m, char type) +{ + m->mtype = type; +} + +char msgbuf_get(msgbuf* m) +{ + return m->mtext[0]; +} + +/// Nombres de los procesos +enum proc_t { PRODUCTOR1, PRODUCTOR2, PRODUCTOR3, CONSUMIDOR1, CONSUMIDOR2 }; + +/// Nombres de los procesos +enum msg_t { PARTE11 = 1, PARTE21, PARTE31, PARTE12, PARTE22, PARTE32 }; + +msg_t msg_types[3][2] = +{ + { PARTE11, PARTE12 }, + { PARTE21, PARTE22 }, + { PARTE31, PARTE32 } +}; + +#define TEST(v) do { if ((v) == -1) { perror("P02e2221"); exit(200); } } while (0) + +void producir(int que_id, int parte) +{ + char val = rand(); + msgbuf msg; + msgbuf_init(&msg, val, msg_types[parte][0]); + TEST(msgsnd(que_id, &msg, 1, 0)); + //sched_yield(); + msgbuf_set_type(&msg, msg_types[parte][1]); + TEST(msgsnd(que_id, &msg, 1, 0)); + //sched_yield(); + cout << "Producida parte " << parte << ": " << (int)val << endl; + sched_yield(); +} + +void consumir(int que_id, int consumidor) +{ + int completo[3]; + msgbuf msg; + TEST(msgrcv(que_id, &msg, 1, msg_types[0][consumidor], 0)); + //sched_yield(); + completo[0] = msg.mtext[0]; + TEST(msgrcv(que_id, &msg, 1, msg_types[1][consumidor], 0)); + //sched_yield(); + completo[1] = msg.mtext[0]; + TEST(msgrcv(que_id, &msg, 1, msg_types[2][consumidor], 0)); + //sched_yield(); + completo[2] = msg.mtext[0]; + cout << "Consumidor " << consumidor << " consumió: " << completo[0] << "," + << completo[1] << "," << completo[2] << endl; + sched_yield(); +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n"; + return 1; + } + proc_t proc = (proc_t) atoi(argv[1]); + + // Cola + int que_id; + do + { + // crea solo si es el proceso 0 + que_id = msgget(MSG_KEY, (proc ? 0 : IPC_CREAT) | 0666); + } + while (proc != PRODUCTOR1 && que_id == -1); + + // Maxima cantidad de iteraciones (puede venir por parametro) + int max_iter = 10; + if (argc > 2) + max_iter = atoi(argv[2]); + + srand(getpid()); + + // Loop principal + for (int i = 0; i < max_iter; ++i) + { + if (proc < 3) // productor + producir(que_id, proc); + else + consumir(que_id, proc-3); + } + + return 0; +} + +// vim: set et sw=4 sts=4 : diff --git a/practicas/practica2/P02e2221.sh b/practicas/practica2/P02e2221.sh new file mode 100755 index 0000000..af2e8e8 --- /dev/null +++ b/practicas/practica2/P02e2221.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +# Lanzo procesos +# Productores +./P02e2221 0 $1 & +p0=$! +./P02e2221 1 $1 & +p1=$! +./P02e2221 2 $1 & +p2=$! +# Consumidores +./P02e2221 3 $1 & +p3=$! +./P02e2221 4 $1 & +p4=$! + +# Espero que terminen +wait $p0 +wait $p01 +wait $p02 +wait $p03 +wait $p04 + +# Limpio IPC +ipcrm -Q 0x77891226