Programa escritor con cola de mensajes y semáforos en C: ejemplo de IPC System V

Informática3,51 KB

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", ...) a scanf("%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 SESC y SLEC deben estar definidas (índices 0 y 1 de los semáforos) para que el código compile.

Descargar

PDF Word HTML