2 * Leandro Lucarella (77891)
4 * Ejercicio 2.1.1. Implementa productor-consumidor con semaforos binarios y
12 #include <sys/types.h>
21 /// Clave de nuestro segmento shm y semaforo
22 #define SHM_KEY 0x77891220
23 #define SEM_KEY 0x77891221
25 /// Elemento a producir/consumir
28 /// Nombres de los semaforos a utilizar
29 enum sem_num_t { MUTEX, FULL, EMPTY };
31 /// Nombres de los procesos
32 enum proc_t { PRODUCTOR, CONSUMIDOR };
34 /// Hace un wait (P) al semaforo (devuelve false si hubo error).
35 void sem_wait(int sem_id, sem_num_t sem_num)
38 op.sem_op = -1; // sacar 1
39 op.sem_num = sem_num; // al semaforo sem_num
40 op.sem_flg = 0; // esperando
41 if (semop(sem_id, &op, 1) > 0)
43 cerr << "No se pudo sacar al semaforo.\n";
48 /// Hace un signal (V) al semaforo (devuelve false si hubo error).
49 void sem_signal(int sem_id, sem_num_t sem_num)
52 op.sem_op = 1; // agregar 1
53 op.sem_num = sem_num; // al semaforo sem_num
54 op.sem_flg = 0; // esperando
55 if (semop(sem_id, &op, 1) > 0)
57 cerr << "No se pudo poner al semaforo.\n";
62 void productor(int sem_id, Elemento* elem)
65 // espera que este vacio segun sea productor
66 sem_wait(sem_id, EMPTY);
67 sem_wait(sem_id, MUTEX); // lock
70 sem_signal(sem_id, MUTEX); // unlock
71 // indica que esta lleno
72 cout << "Productor puso elem = " << val << endl;
73 sem_signal(sem_id, FULL);
76 void consumidor(int sem_id, Elemento* elem)
79 // espera que este lleno segun sea consumidor
80 sem_wait(sem_id, FULL);
81 sem_wait(sem_id, MUTEX); // lock
84 sem_signal(sem_id, MUTEX); // unlock
85 // indica que esta vacio
86 cout << "Consumidor saco elem = " << val << endl;
87 sem_signal(sem_id, EMPTY);
90 int main(int argc, char *argv[])
94 cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
97 proc_t proc = (proc_t) atoi(argv[1]);
103 shm_id = shmget(SHM_KEY, sizeof(Elemento),
104 (proc ? 0 : IPC_CREAT) | 0666); // crea solo si es el proceso 0
106 while (proc == CONSUMIDOR && shm_id == -1);
107 Elemento* elem = (Elemento*) shmat(shm_id, NULL, 0);
108 if (elem == (Elemento*) -1)
110 cerr << "Error al attachear shared memory.\n";
118 sem_id = semget(SEM_KEY, 3,
119 (proc ? 0 : IPC_CREAT) | 0666); // crea solo si es el proceso 0
121 while (proc == CONSUMIDOR && sem_id == -1);
123 // Si somos los primeros inicializamos
124 if (proc == PRODUCTOR)
126 if (semctl(sem_id, MUTEX, SETVAL, 1) < 0)
128 cerr << "No se pudo inicializar semaforo.\n";
131 if (semctl(sem_id, FULL, SETVAL, 0) < 0)
133 cerr << "No se pudo inicializar semaforo.\n";
136 if (semctl(sem_id, EMPTY, SETVAL, 1) < 0)
138 cerr << "No se pudo inicializar semaforo.\n";
143 // Maxima cantidad de iteraciones (puede venir por parametro)
146 max_iter = atoi(argv[2]);
151 for (int i = 0; i < max_iter; ++i)
153 if (proc == PRODUCTOR)
154 productor(sem_id, elem);
156 consumidor(sem_id, elem);
159 if (shmdt(elem) == -1)
161 cerr << "Error al detachear shared memory.\n";
168 // vim: set et sw=4 sts=4 :