El primer procso pone el número 1 en la variable compartida, después, el segundo proceso lee el valor 1 y lo muestra por pantalla. Después el primer proceso pone el número 2 en la variable compartida, y así hasta el 5.
Para sincronizar ambos procesos se han utilizado dos grupos de un semáforo cada uno.
#include < errno.h>
#include < stdio.h>
#include < unistd.h>
#include < wait.h>
#include < sys/ipc.h>
#include < sys/sem.h>
#include < sys/stat.h>
#include < sys/types.h>
#include "sv.h"
union senum {
int val;
};
int main() {
pid_t pid;
int c, r;
int num;
int sem_prod, sem_cons;
struct sembuf arriba = {0,1,0};
struct sembuf abajo = {0,-1,0};
union senum arg;
sv_init();
sem_prod = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
sem_cons = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
if ((sem_prod == -1) || (sem_cons==-1)) {
perror("Error creando semáforos");
return -1;
}
arg.val = 1;
r = semctl(sem_prod, 0, SETVAL, arg);
if (r == -1) {
perror("Error incializando el semáforo del productor - ");
//Borrar los semáforos
return -1;
}
for (c = 0; c < 2; c++) {
pid = fork();
if (pid == -1) {
perror("Error creando procesos - ");
// Borrar semáforos.
return -1;
}
if (pid == 0) {
// Productor
if (c==0) {
for (num = 1; num < 6; num++) {
// Mi turno de producir
r = semop(sem_prod, &abajo, 1);
if (r == -1) {
perror("Error bajando el semáforo del productor - ");
// Eliminar semáforos
return -1;
}
printf("Valor producido: %i\n", num);
sv_set(num);
// El turno de consumir
r = semop(sem_cons, &arriba, 1);
if (r == -1) {
perror("Error subiendo el semáforo del consumidor - ");
// Eso
return -1;
}
}
exit(0);
}
// Consumidor
if (c==1) {
for (num = 0; num < 5; num++) {
// Voy a consumir 5 números
r = semop(sem_cons, &abajo, 1);
if (r == -1) {
perror("Error bajando semáforo del consumidor - ");
return -1;
}
printf("Valor consumido: %i\n", sv_get() );
// Hora de producir
r = semop(sem_prod, &arriba, 1);
if (r == -1) {
perror("Error subiendo semáforo del productos - ");
return -1;
}
}
exit(0);
}
}
}
pid = wait(&r);
while ( (pid != -1) ||
( (pid == -1) && (errno == EINTR)) )
pid = wait(&r);
r = semctl(sem_prod, 0, IPC_RMID);
if (r==-1) {
perror("Error eliminando semáforo productor.");
}
r = semctl(sem_cons, 0, IPC_RMID);
if (r == -1) {
perror("Error eliminando semáforo consumidor. ");
}
sv_finish();
printf("Fin.\n");
return 0;
}