]> git.llucax.com Git - z.facultad/75.74/practicos.git/blobdiff - practicas/practica2/P02e2111.cpp
Ejercicio 2.2.2 terminado y andando.
[z.facultad/75.74/practicos.git] / practicas / practica2 / P02e2111.cpp
index 1a5c8d78646b38755c5fc8da7285247dc4882a67..932638fb06509b00a4f6a6cb9510140efa38490d 100644 (file)
 #include <sys/shm.h>
 #include <sys/sem.h>
 
+using std::cerr;
+using std::cout;
+using std::endl;
+
 /// Clave de nuestro segmento shm y semaforo
 #define SHM_KEY 0x77891220
 #define SEM_KEY 0x77891221
@@ -30,131 +34,135 @@ enum proc_t { PRODUCTOR, CONSUMIDOR };
 /// Hace un wait (P) al semaforo (devuelve false si hubo error).
 void sem_wait(int sem_id, sem_num_t sem_num)
 {
-       struct sembuf op;
-       op.sem_op = -1; // sacar 1
-       op.sem_num = sem_num; // al semaforo sem_num
-       op.sem_flg = 0; // esperando
-       if (semop(sem_id, &op, 1) > 0)
-       {
-               std::cerr << "No se pudo sacar al semaforo.\n";
-               exit(100);
-       }
+    struct sembuf op;
+    op.sem_op = -1; // sacar 1
+    op.sem_num = sem_num; // al semaforo sem_num
+    op.sem_flg = 0; // esperando
+    if (semop(sem_id, &op, 1) > 0)
+    {
+        cerr << "No se pudo sacar al semaforo.\n";
+        exit(100);
+    }
 }
 
 /// Hace un signal (V) al semaforo (devuelve false si hubo error).
 void sem_signal(int sem_id, sem_num_t sem_num)
 {
-       struct sembuf op;
-       op.sem_op =  1; // agregar 1
-       op.sem_num = sem_num; // al semaforo sem_num
-       op.sem_flg = 0; // esperando
-       if (semop(sem_id, &op, 1) > 0)
-       {
-               std::cerr << "No se pudo poner al semaforo.\n";
-               exit(101);
-       }
+    struct sembuf op;
+    op.sem_op =  1; // agregar 1
+    op.sem_num = sem_num; // al semaforo sem_num
+    op.sem_flg = 0; // esperando
+    if (semop(sem_id, &op, 1) > 0)
+    {
+        cerr << "No se pudo poner al semaforo.\n";
+        exit(101);
+    }
+}
+
+void productor(int sem_id, Elemento* elem)
+{
+        int val = rand();
+        // espera que este vacio segun sea productor
+        sem_wait(sem_id, EMPTY);
+        sem_wait(sem_id, MUTEX); // lock
+        // produzco
+        *elem = val;
+        sem_signal(sem_id, MUTEX); // unlock
+        // indica que esta lleno
+        cout << "Productor puso elem = " << val << endl;
+        sem_signal(sem_id, FULL);
+}
+
+void consumidor(int sem_id, Elemento* elem)
+{
+        int val;
+        // espera que este lleno segun sea consumidor
+        sem_wait(sem_id, FULL);
+        sem_wait(sem_id, MUTEX); // lock
+        // consumo
+        val = *elem;
+        sem_signal(sem_id, MUTEX); // unlock
+        // indica que esta vacio
+        cout << "Consumidor saco elem = " << val << endl;
+        sem_signal(sem_id, EMPTY);
 }
 
 int main(int argc, char *argv[])
 {
-       using std::cerr;
-       using std::cout;
-
-       if (argc < 2)
-       {
-               cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
-               return 1;
-       }
-       proc_t proc = (proc_t) atoi(argv[1]);
-
-       // Shared memory
-       int shm_id = shmget(SHM_KEY, sizeof(Elemento), IPC_CREAT | 0666);
-       if (shm_id == -1)
-       {
-               cerr << "Error al crea/obtener shared memory.\n";
-               return 2;
-       }
-       Elemento* elem = (Elemento*) shmat(shm_id, NULL, 0);
-       if (elem == (Elemento*) -1)
-       {
-               cerr << "Error al attachear shared memory.\n";
-               return 3;
-       }
-       cout << "Shared memory id = " << shm_id << "\n";
-
-       // Semaforos
-       int sem_id = semget(SEM_KEY, 3, 0666 | IPC_CREAT);
-       if (sem_id == -1)
-       {
-               cerr << "Error al crea/obtener semaforos.\n";
-               return 4;
-       }
-       // Si somos los primeros inicializamos
-       if (!proc)
-       {
-               if (semctl(sem_id, MUTEX, SETVAL, 1) < 0)
-               {
-                       cerr << "No se pudo inicializar semaforo.\n";
-                       return 5;
-               }
-               if (semctl(sem_id, FULL, SETVAL, 0) < 0)
-               {
-                       cerr << "No se pudo inicializar semaforo.\n";
-                       return 6;
-               }
-               if (semctl(sem_id, EMPTY, SETVAL, 1) < 0)
-               {
-                       cerr << "No se pudo inicializar semaforo.\n";
-                       return 7;
-               }
-               cout << "Semaforos inicializados id = " << sem_id << "\n";
-       }
-       else // Si soy otro espero un poco por las dudas para que corra el 1ro
-       {
-               usleep(1000);
-       }
-
-       // Maxima cantidad de iteraciones (puede venir por parametro)
-       int max_iter = 10;
-       if (argc > 2)
-               max_iter = atoi(argv[2]);
-
-       // Loop principal
-       for (int i = 0; i < max_iter; ++i)
-       {
-               int val = rand();
-               // espera que este lleno/vacio segun sea consumidor/productor
-               if (proc == PRODUCTOR)
-                       sem_wait(sem_id, EMPTY);
-               else
-                       sem_wait(sem_id, FULL);
-               sem_wait(sem_id, MUTEX); // lock
-               // produzco / consumo
-               if (proc == PRODUCTOR)
-                       *elem = val;
-               else
-                       val = *elem;
-               sem_signal(sem_id, MUTEX); // unlock
-               // indica que esta lleno/vacio segun sea productor/consumidor
-               if (proc == PRODUCTOR)
-               {
-                       cout << "Productor (" << getpid() << ") puso elem = "
-                               << val << std::endl;
-                       sem_signal(sem_id, FULL);
-               }
-               else
-               {
-                       cout << "Consumidor (" << getpid() << ") saco elem = "
-                               << val << std::endl;
-                       sem_signal(sem_id, EMPTY);
-               }
-       }
-
-       if (shmdt(elem) == -1)
-       {
-               cerr << "Error al detachear shared memory.\n";
-               return -1;
-       }
-
-       return 0;
+    if (argc < 2)
+    {
+        cerr << "Faltan parametros: " << argv[0] << " N [max_iter]\n";
+        return 1;
+    }
+    proc_t proc = (proc_t) atoi(argv[1]);
+
+    // Shared memory
+    int shm_id;
+    do
+    {
+        shm_id = shmget(SHM_KEY, sizeof(Elemento),
+            (proc ? 0 : IPC_CREAT) | 0666); // crea solo si es el proceso 0
+    }
+    while (proc == CONSUMIDOR && shm_id == -1);
+    Elemento* elem = (Elemento*) shmat(shm_id, NULL, 0);
+    if (elem == (Elemento*) -1)
+    {
+        cerr << "Error al attachear shared memory.\n";
+        return 3;
+    }
+
+    // Semaforos
+    int sem_id;
+    do
+    {
+        sem_id = semget(SEM_KEY, 3,
+            (proc ? 0 : IPC_CREAT) | 0666); // crea solo si es el proceso 0
+    }
+    while (proc == CONSUMIDOR && sem_id == -1);
+
+    // Si somos los primeros inicializamos
+    if (proc == PRODUCTOR)
+    {
+        if (semctl(sem_id, MUTEX, SETVAL, 1) < 0)
+        {
+            cerr << "No se pudo inicializar semaforo.\n";
+            return 5;
+        }
+        if (semctl(sem_id, FULL, SETVAL, 0) < 0)
+        {
+            cerr << "No se pudo inicializar semaforo.\n";
+            return 6;
+        }
+        if (semctl(sem_id, EMPTY, SETVAL, 1) < 0)
+        {
+            cerr << "No se pudo inicializar semaforo.\n";
+            return 7;
+        }
+    }
+
+    // Maxima cantidad de iteraciones (puede venir por parametro)
+    int max_iter = 10;
+    if (argc > 2)
+        max_iter = atoi(argv[2]);
+
+    srand(getpid());
+
+    // Loop principal
+    for (int i = 0; i < max_iter; ++i)
+    {
+        if (proc == PRODUCTOR)
+            productor(sem_id, elem);
+        else
+            consumidor(sem_id, elem);
+    }
+
+    if (shmdt(elem) == -1)
+    {
+        cerr << "Error al detachear shared memory.\n";
+        return -1;
+    }
+
+    return 0;
 }
+
+// vim: set et sw=4 sts=4 :