LINUX.ORG.RU

Сообщения zen_2_

 

проблема с чтением из FIFO

Доброго времени суток. Стоит задача по реализации программы с разделением на процессы, использующих в качестве средства взаимодействия именованные каналы. Краткое описание задачи: Родитель передает три строки, потомок возвращает самую короткую из них.

#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define FIFO_NAME "my_fifo"

void hdl(int sig) {
    if(sig == SIGUSR1)
    printf("SIGUSR1...\n");
    else if(sig == SIGUSR2)
    printf("SIGUSR2...\n");
    else
    printf("Something else\n");
}
int main() {
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = hdl;
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGUSR1);
    sigaddset(&set, SIGUSR2);
    act.sa_mask = set;
    sigaction(SIGUSR1, &act, 0);
    sigaction(SIGUSR2, &act, 0);
    signal(SIGUSR1, hdl);
    int sig;
    pid_t pid;

    char str1[100], str2[100], str3[100];
    char shortest[100];

    int fd_fifo; /* дескриптор FIFO */

    /* Если файл с таким именем существует, удалим его */
    unlink(FIFO_NAME);

    /* Обнуляем маску прав */
    (void)umask(0);

    /* Создаем FIFO */
    if ((mkfifo(FIFO_NAME, 0666)) == -1) {
        perror("Невозможно создать fifo\n");
        exit(0);
    }

    pid=fork();
    if (pid>0) {
        printf("parent...\n");
        printf("Pid = %d\n",getpid() );

        printf("Введите первую строку: ");
        fgets(str1, sizeof(str1), stdin);
        printf("Введите вторую строку: ");
        fgets(str2, sizeof(str2), stdin);
        printf("Введите третью строку: ");
        fgets(str3, sizeof(str3), stdin);
        /* Открываем fifo для чтения и записи */
        if ((fd_fifo = open(FIFO_NAME, O_RDWR)) == -1) {
            perror("Невозможно открыть fifo\n");
            exit(0);
        }

        /* Записываем в fifo */
        //write(fd_fifo,buffer,strlen(buffer)) ;
        write(fd_fifo, str1, strlen(str1) + 1);
        write(fd_fifo, str2, strlen(str2) + 1);
        write(fd_fifo, str3, strlen(str3) + 1);
        close(fd_fifo);

        //посылаем сигнал дочернему процессу
        kill(pid, SIGUSR1);
        sigemptyset(&set);
        sigaddset(&set, SIGUSR2);
        printf("parent wait signal...\n");

        //ожидаем сигнал SIGUSR1
        sigwait(&set, &sig);
        printf("parent exit...\n");

        /* Открываем fifo для чтения и записи */
        if ((fd_fifo = open(FIFO_NAME, O_RDWR|O_NONBLOCK)) == -1) {
            perror("Невозможно открыть fifo\n");
            exit(0);
        }

        // Читаем самую короткую строку от дочернего процесса
        read(fd_fifo, shortest, sizeof(shortest));
        printf("Родитель получил от потомка самую короткую строку: %s\n", shortest);
        close(fd_fifo);

        }
        else if (pid==0){ //дочерний процесс
            sigemptyset(&set);
            sigaddset(&set, SIGUSR1);
            //ожидаем сигнал SIGUSR1
            sigwait(&set, &sig);
            printf("child...\n");
            printf("Pid = %d\n",getpid() );
            printf("work...\n");

            /* Открываем fifo для чтения и записи */
            if ((fd_fifo = open(FIFO_NAME, O_RDWR)) == -1) {
                perror("Невозможно открыть fifo\n");
                exit(0);
            }

            // Чтение строк от родителя
            if(read(fd_fifo, str1, sizeof(str1)) == -1)
                perror("Невозможно прочесть str1 из FIFO\n");
            if(read(fd_fifo, str2, sizeof(str2)) == -1)
                perror("Невозможно прочесть str2 из FIFO\n");
            if(read(fd_fifo, str3, sizeof(str3)) == -1)
                perror("Невозможно прочесть str3 из FIFO\n");
            close(fd_fifo);

            printf("Дочерний процесс получил три строки от родителя.\n");
            printf("%s\n, %s\n, %s\n", str1, str2, str3);

            // Находим самую короткую строку
            strcpy(shortest, str1);
            if (strlen(str2) < strlen(shortest)) {
                strcpy(shortest, str2);
            }
            if (strlen(str3) < strlen(shortest)) {
                strcpy(shortest, str3);
            }
            printf("Дочерний процесс вычислил самую короткую строку: %s\n", shortest);

            /*открываем fifo для чтения и записи */
            if ((fd_fifo = open(FIFO_NAME, O_RDWR)) == -1) {
                perror("Невозможно открыть fifo\n");
                exit(0);
            }

            // Записываем самую короткую строку в FIFO
            write(fd_fifo, shortest, strlen(shortest) + 1);
            printf("Дочерний процесс отправил родителю самую короткую строку: %s\n", shortest);
            close(fd_fifo);

            sleep(5);
            //посылаем сигнал родительскому процессу
            kill(getppid(), SIGUSR2);
            printf("child exit...\n");
            exit(0);
        }
    return 0;
}

программа зависает на моменте открытия FIFO в дочернем процессе, но ошибку при этом не выдает

parent...
Pid = 13172
Введите первую строку: a
Введите вторую строку: aa
Введите третью строку: aaa
parent wait signal...
child...
Pid = 13173
work...

 ,

zen_2_
()

RSS подписка на новые темы