2 * Leandro Lucarella (77891)
4 * Ejercicio 2.1.1. Implementa productor-consumidor con semaforos binarios y
12 #include <sys/types.h>
17 /// Clave de nuestro segmento shm y semaforo
18 #define SHM_KEY 0x77891220
19 #define SEM_KEY 0x77891221
21 /// Elemento a producir/consumir
24 /// Nombres de los semaforos a utilizar
25 enum sem_num_t { MUTEX, FULL, EMPTY };
27 /// Nombres de los procesos
28 enum proc_t { PRODUCTOR, CONSUMIDOR };
30 /// Hace un wait (P) al semaforo (devuelve false si hubo error).
31 void sem_wait(int sem_id, sem_num_t sem_num)
34 op.sem_op = -1; // sacar 1
35 op.sem_num = sem_num; // al semaforo sem_num
36 op.sem_flg = 0; // esperando
37 if (semop(sem_id, &op, 1) > 0)
39 std::cerr << "No se pudo sacar al semaforo.\n";
44 /// Hace un signal (V) al semaforo (devuelve false si hubo error).
45 void sem_signal(int sem_id, sem_num_t sem_num)
48 op.sem_op = 1; // agregar 1
49 op.sem_num = sem_num; // al semaforo sem_num
50 op.sem_flg = 0; // esperando
51 if (semop(sem_id, &op, 1) > 0)
53 std::cerr << "No se pudo poner al semaforo.\n";
58 int main(int argc, char *argv[])
65 cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
68 proc_t proc = (proc_t) atoi(argv[1]);
71 int shm_id = shmget(SHM_KEY, sizeof(Elemento), IPC_CREAT | 0666);
74 cerr << "Error al crea/obtener shared memory.\n";
77 Elemento* elem = (Elemento*) shmat(shm_id, NULL, 0);
78 if (elem == (Elemento*) -1)
80 cerr << "Error al attachear shared memory.\n";
83 cout << "Shared memory id = " << shm_id << "\n";
86 int sem_id = semget(SEM_KEY, 3, 0666 | IPC_CREAT);
89 cerr << "Error al crea/obtener semaforos.\n";
92 // Si somos los primeros inicializamos
95 if (semctl(sem_id, MUTEX, SETVAL, 1) < 0)
97 cerr << "No se pudo inicializar semaforo.\n";
100 if (semctl(sem_id, FULL, SETVAL, 0) < 0)
102 cerr << "No se pudo inicializar semaforo.\n";
105 if (semctl(sem_id, EMPTY, SETVAL, 1) < 0)
107 cerr << "No se pudo inicializar semaforo.\n";
110 cout << "Semaforos inicializados id = " << sem_id << "\n";
112 else // Si soy otro espero un poco por las dudas para que corra el 1ro
117 // Maxima cantidad de iteraciones (puede venir por parametro)
120 max_iter = atoi(argv[2]);
123 for (int i = 0; i < max_iter; ++i)
126 // espera que este lleno/vacio segun sea consumidor/productor
127 if (proc == PRODUCTOR)
128 sem_wait(sem_id, EMPTY);
130 sem_wait(sem_id, FULL);
131 sem_wait(sem_id, MUTEX); // lock
132 // produzco / consumo
133 if (proc == PRODUCTOR)
137 sem_signal(sem_id, MUTEX); // unlock
138 // indica que esta lleno/vacio segun sea productor/consumidor
139 if (proc == PRODUCTOR)
141 cout << "Productor (" << getpid() << ") puso elem = "
143 sem_signal(sem_id, FULL);
147 cout << "Consumidor (" << getpid() << ") saco elem = "
149 sem_signal(sem_id, EMPTY);
153 if (shmdt(elem) == -1)
155 cerr << "Error al detachear shared memory.\n";