]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/practica2/P02e2321.cpp
Ya estamos fragmentando! (falta testing intensivo pero parece andar)
[z.facultad/75.74/practicos.git] / practicas / practica2 / P02e2321.cpp
1 /**
2  * Leandro Lucarella (77891)
3  *
4  * Ejercicio 2.3.2. Implementa productor-consumidor con pipes, con 3
5  * productores que producen 1/3 cada uno y 2 consumidores que consumen todo.
6  */
7
8 #include <iostream>
9 #include <sstream>
10 #include <cstdlib>
11 #include <unistd.h>
12 #include <fcntl.h>
13 #include <sys/types.h>
14 #include <sys/ipc.h>
15 #include <sys/msg.h>
16
17 using std::cerr;
18 using std::cout;
19 using std::endl;
20 using std::ostringstream;
21
22 // Nombre base del pipe
23 #define PIPE_BASE "77891_P02e2321_"
24
25 /// Nombres de los procesos
26 enum proc_t { PRODUCTOR1, PRODUCTOR2, PRODUCTOR3, CONSUMIDOR1, CONSUMIDOR2 };
27
28 #define TEST(v) do { if ((v) == -1) { perror("P02e2221"); exit(200); } } while (0)
29
30 void producir(int pipes[], int parte)
31 {
32     int val = rand();
33     TEST(write(pipes[0], &val, sizeof(int)));
34     TEST(write(pipes[1], &val, sizeof(int)));
35     cout << "Producida parte " << parte  << ": " << (int)val << endl;
36 }
37
38 void consumir(int pipes[], int consumidor)
39 {
40     int completo[3];
41     TEST(read(pipes[0], &completo[0], sizeof(int)));
42     TEST(read(pipes[1], &completo[1], sizeof(int)));
43     TEST(read(pipes[2], &completo[2], sizeof(int)));
44     cout << "Consumidor " << consumidor << " consumió: " << completo[0] << ","
45         << completo[1] << "," << completo[2] << endl;
46 }
47
48 int main(int argc, char *argv[])
49 {
50     srand(getpid());
51
52     if (argc < 2)
53     {
54         cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
55         return 1;
56     }
57     proc_t proc = (proc_t) atoi(argv[1]);
58
59     // Maxima cantidad de iteraciones (puede venir por parametro)
60     int max_iter = 10;
61     if (argc > 2)
62         max_iter = atoi(argv[2]);
63
64     // Abro pipes según corresponda
65     int pipes[3];
66     if (proc <= PRODUCTOR3) // Productores
67     {
68         ostringstream oss;
69         oss << PIPE_BASE << proc << "_0";
70         pipes[0] = open(oss.str().c_str(), O_WRONLY);
71         TEST(pipes[0]);
72         oss.str("");
73         oss << PIPE_BASE << proc << "_1";
74         pipes[1] = open(oss.str().c_str(), O_WRONLY);
75         TEST(pipes[1]);
76     }
77     else // Consumidores
78     {
79         int consumidor = proc-3;
80         ostringstream oss;
81         oss << PIPE_BASE << "0_" << consumidor;
82         pipes[0] = open(oss.str().c_str(), O_RDONLY);
83         TEST(pipes[0]);
84         oss.str("");
85         oss << PIPE_BASE << "1_" << consumidor;
86         pipes[1] = open(oss.str().c_str(), O_RDONLY);
87         TEST(pipes[1]);
88         oss.str("");
89         oss << PIPE_BASE << "2_" << consumidor;
90         pipes[2] = open(oss.str().c_str(), O_RDONLY);
91         TEST(pipes[2]);
92     }
93
94     for (int i = 0; i < max_iter; ++i)
95     {
96         if (proc <= PRODUCTOR3)
97             producir(pipes, proc);
98         else
99             consumir(pipes, proc-3);
100         sched_yield();
101     }
102
103     return 0;
104 }
105
106 // vim: set et sw=4 sts=4 :