--- /dev/null
+/**
+ * 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 <iostream>
+#include <cstdlib>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+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 :