2 * Leandro Lucarella (77891)
4 * Ejercicio 1.2. Implementa problema del museo usando variables (shared memory)
12 #include <sys/types.h>
17 /// Clave de nuestro segmento shm y semaforo
18 #define SHM_KEY 0x77891120
19 #define SEM_KEY 0x77891121
21 /// Ahora el contador es un simple unsigned
22 typedef unsigned Molinete;
24 /// Hace un wait (P) al semaforo (devuelve false si hubo error).
25 void sem_wait(int sem_id)
28 op.sem_op = -1; // sacar 1
29 op.sem_num = 0; // al semaforo 1
30 op.sem_flg = 0; // esperando
31 if (semop(sem_id, &op, 1) < 0)
33 std::cerr << "No se pudo sacar al semaforo.\n";
38 /// Hace un signal (V) al semaforo (devuelve false si hubo error).
39 void sem_signal(int sem_id)
42 op.sem_op = 1; // agregar 1
43 op.sem_num = 0; // al semaforo 1
44 op.sem_flg = 0; // esperando
45 if (semop(sem_id, &op, 1) < 0)
47 std::cerr << "No se pudo poner en el semaforo.\n";
52 int main(int argc, char *argv[])
59 cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
62 int proc = atoi(argv[1]);
65 int shm_id = shmget(SHM_KEY, sizeof(Molinete), IPC_CREAT | 0666);
68 cerr << "Error al crea/obtener shared memory.\n";
71 Molinete* molinete = (Molinete*) shmat(shm_id, NULL, 0);
72 if (molinete == (Molinete*) -1)
74 cerr << "Error al attachear shared memory.\n";
77 cout << "Shared memory id = " << shm_id << "\n";
80 int sem_id = semget(SEM_KEY, 1, 0666 | IPC_CREAT);
83 cerr << "Error al crea/obtener semaforo.\n";
86 // Si es el primero, inicializo
90 if (semctl(sem_id, 0, SETVAL, 1) < 0) // pongo 1 en el sem
92 cerr << "No se pudo inicializar semaforo.\n";
95 cout << "Semaforo inicializado id = " << sem_id << "\n";
97 else // Si soy otro espero un poco por las dudas para que corra el 1ro
104 // Maxima cantidad de iteraciones (puede venir por parametro)
105 int max_iter = 100000;
107 max_iter = atoi(argv[2]);
110 for (int i = 0; i < max_iter; ++i)
112 char sdec[] = "sale";
113 char sinc[] = "entra";
115 bool dec = rand() % 2;
117 sem_wait(sem_id); // lock
118 if (dec && *molinete) // Decremento sólo si no es 0
128 sem_signal(sem_id); // unlock
129 // Uso cout directamente porque es line-buffered, mientras que
130 // no use threads no es problema el buffer de cout. Y de todas
131 // formas pongo un flush (el endl es \n+flush) por las dudas.
132 cout << "Proceso " << proc << " (" << s << "): molinete = " << count
134 sched_yield(); // Para ver como se entrelazan mejor
137 if (shmdt(molinete) == -1)
139 cerr << "Error al detachear shared memory.\n";
146 // vim: set et sw=4 sts=4 :