/// Ahora el contador es un simple unsigned
typedef unsigned Molinete;
-/// Union para utilizar semaforo
-union semun
+/// Hace un wait (P) al semaforo (devuelve false si hubo error).
+bool sem_wait(int sem_id)
{
- int val;
- struct semid_ds* buf;
- unsigned short* array;
-};
+ struct sembuf op;
+ op.sem_op = -1; // sacar 1
+ op.sem_num = 0; // al semaforo 1
+ op.sem_flg = 0; // esperando
+ return semop(sem_id, &op, 1) >= 0;
+}
+
+/// Hace un signal (V) al semaforo (devuelve false si hubo error).
+bool sem_signal(int sem_id)
+{
+ struct sembuf op;
+ op.sem_op = 1; // agregar 1
+ op.sem_num = 0; // al semaforo 1
+ op.sem_flg = 0; // esperando
+ return semop(sem_id, &op, 1) >= 0;
+}
int main(int argc, char *argv[])
{
cerr << "Error al crea/obtener semaforo.\n";
return 4;
}
- semun sem_arg;
- sem_arg.val = 0;
- if (semctl(sem_id, 0, SETVAL, sem_arg) < 0)
+ // Si es el primero, inicializo
+ if (!proc)
{
- cerr << "No se pudo inicializar semaforo.\n";
- return 5;
+ *molinete = 0;
+ if (semctl(sem_id, 0, SETVAL, 1) < 0)
+ {
+ cerr << "No se pudo inicializar semaforo.\n";
+ return 5;
+ }
+ cout << "Semaforo inicializado id = " << sem_id << "\n";
}
- struct sembuf ops;
- ops.sem_op = 1; // agregar 1
- ops.sem_num = 0; // al semaforo 1
- ops.sem_flg = 0; // esperando
- if (semop(sem_id, &ops, 1) < 0)
+ else // Si soy otro espero un poco por las dudas para que corra el 1ro
{
- cerr << "No se pudo agregar al semaforo.\n";
- return 6;
+ usleep(1000);
}
- cout << "Semaforo inicializado id = " << sem_id << "\n";
-
- // Si somos el primer proceso inicializamos el molinete
- if (!proc) *molinete = 0;
// Maxima cantidad de iteraciones (puede venir por parametro)
int max_iter = 100000;
{
bool dec = rand() % 2;
int count;
- // lock
- ops.sem_op = -1; // saco 1 (== adquirir el mutex)
- if (semop(sem_id, &ops, 1) < 0)
+ if (!sem_wait(sem_id)) // lock
{
cerr << "No se pudo sacar al semaforo.\n";
return 6;
}
- if (dec && molinete) // Decremento sólo si no es 0
+ if (dec && *molinete) // Decremento sólo si no es 0
count = --*molinete;
else
count = ++*molinete;
- // unlock
- ops.sem_op = 1; // pongo 1 (== liberar el mutex)
- if (semop(sem_id, &ops, 1) < 0)
+ if (!sem_signal(sem_id)) // unlock
{
cerr << "No se pudo sacar al semaforo.\n";
return 6;