Programa escritor con cola de mensajes y semáforos en C: ejemplo de IPC System V
Programa escritor con cola de mensajes y semáforos
El programa solicita por teclado un nombre de 80 caracteres como máximo, una dirección y un sueldo (entero largo), hasta que se introduzca FIN en el campo nombre. Cada registro se introduce en una cola de mensajes junto con su tipo, que también se lee por teclado.
Mientras se ejecute este programa, no se permitirá que ningún otro proceso manipule la cola de mensajes. Cuando termine la introducción de mensajes, se permitirá que existan como máximo dos procesos que accedan simultáneamente a la cola para extraer mensajes.
Estructura de datos
struct empleados {
long tipo;
char nombre[80];
char dir[80];
long sueldo;
};Código del programa
main() {
int semid, colaid, nb;
struct empleados emple;
struct sembuf op;
key_t llave;
if ((llave = ftok("/", 'A')) == (key_t)-1) {
perror("Error al crear llave");
return 1;
}
if ((semid = semget(llave, 2, IPC_CREAT | 0666)) == -1) {
perror("Error al crear semáforos");
return 1;
}
if ((colaid = msgget(llave, IPC_CREAT | 0666)) == -1) {
perror("Error al crear cola de mensajes");
return 1;
}
if (semctl(semid, SESC, SETVAL, 1) == -1 || semctl(semid, SLEC, SETVAL, 0) == -1) {
perror("Error al inicializar semáforos");
return 1;
}
op.sem_num = SESC;
op.sem_op = -1;
op.sem_flg = 0;
if (semop(semid, &op, 1) == -1) {
perror("Error al adquirir semáforo escritor");
}
puts("Dame nombre");
nb = read(0, emple.nombre, sizeof(emple.nombre));
emple.nombre[nb - 1] = '\0';
while (strcmp(emple.nombre, "FIN") != 0) {
fflush(stdin);
puts("Dame tipo");
scanf("%ld", &emple.tipo);
do {
puts("Dame el tipo <1,2,3>\n");
scanf("%ld", &emple.tipo);
} while (emple.tipo < 1 || emple.tipo > 3);
fflush(stdin);
puts("Dame dirección");
nb = read(0, emple.dir, sizeof(emple.dir));
emple.dir[nb - 1] = '\0';
fflush(stdin);
puts("Dame sueldo");
scanf("%ld", &emple.sueldo);
if (msgsnd(colaid, &emple, sizeof(emple) - sizeof(long), IPC_NOWAIT) == -1) {
perror("Error al mandar datos a la cola");
break;
}
printf("Información enviada\n");
puts("Dame nombre");
nb = read(0, emple.nombre, sizeof(emple.nombre));
emple.nombre[nb - 1] = '\0';
}
op.sem_num = SLEC;
op.sem_op = +1;
op.sem_flg = 0;
if (semop(semid, &op, 1) == -1) {
perror("Error al liberar semáforo lector");
}
printf("Pulse para borrar IPCs\n");
getchar();
fflush(stdin);
if (semctl(semid, 0, IPC_RMID, 0) == -1)
perror("Error al borrar semáforos");
if (msgctl(colaid, IPC_RMID, 0) == -1)
perror("Error al borrar cola");
}Observaciones
- Se corrigió el formato
scanf("&ld", ...)ascanf("%ld", ...). - Se añadió el punto y coma que faltaba tras
emple.dir[nb-1]='\0'. - Se completaron las llaves de cierre del bucle
while, que en el original aparecían fusionadas. - La constante
SESCySLECdeben estar definidas (índices 0 y 1 de los semáforos) para que el código compile.