LINUX.ORG.RU

Необычное поведение при использовании каналов из <unistd.h>

 , ,


0

1

Нужно написать программу на Си использующую несколько процессов. При написании столкнулся с необычной проблемой. При вызове write(pipe[1], string, strlen(stirng) в стандартный вывод подаётся содержимое строки. Сама программа выглядит вот так:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>


int main(void) 
{
    int clientPipe[2];
    int* size = malloc(sizeof(int));
    char string[] = "Hello, world!\n";


    pid_t childpid;
    
    if ((childpid = fork()) == -1) {
        perror("fork");
        exit(1);
    } else if (childpid == 0) {
        /* Client */

        close(clientPipe[0]);

/*        scanf("%d", size);*/
/*        printf("%d\n", *size);*/
        /* write(clientPipe[1], size, sizeof(int)); */
        write(clientPipe[1], string, sizeof(string));
        printf("TROLOLO\n");

/*        time_t rawtime;*/
/*        srand(rawtime);*/
        exit(0);
    } else {
        /* Server */
    
        wait();
        close(clientPipe[1]);
        printf("Continue\n");
        *size = read(clientPipe[0], string, sizeof(string));
        printf("%s", string);
/*        read(clientPipe[0], size, sizeof(int));*/
/*        printf("%d\n", *size);*/
    }
       
    return(0);
}

Вывод при запуске следующий:

TROLOLO
Hello, world!
Continue
Hello, world!
}

Почему Hello, world! выводится дважды?

И, в дополнение, когда нужно вызывать wait()? До закрытия канала и считывания или после?

Ну и раз уж зашла речь о wait(), почему при компиляции (clang source.c) я получаю следующий варнинг и как мне его не получать (гугл не помог):

hello.c:37:9: warning: implicit declaration of function 'wait' is invalid in C99
      [-Wimplicit-function-declaration]
        wait();

int clientPipe[2]; инициализировать не пробовал? Ну там pipe(int pipefd[2]); вызывать, вот это вот всё? Лол.

В clientPipe у тебя походу нули, т.е. в «клиенте» ты тупо пишешь в stdout.
А в «сервере» нифига не читается, т.к. на чтение не открыто и переменная string остаётся нетронутой.

Попробуй для начала хотя бы возвращаемые значения проверять и обрабатывать ошибки.

anonymous ()

В качестве дополнения.

Необычное поведение при использовании каналов из <unistd.h>

Да, твоё поведение очень необычное. Обычно вызывают pipe() и проверяют возвращаемые значения.

anonymous ()

malloc вызывать не нужно. man 2 wait посмотри что нужно инклудить. Про pipe и clientPipe уже сказали

redixin ★★★★ ()
Ответ на: комментарий от anonymous

инициализировать не пробовал?

А, блин, затупил, уж ночь, поздно, а сдавать нужно совсем скоро. Спасибо всем кто обратил внимание.

zoroaster ()
Ответ на: комментарий от zoroaster

А, блин, затупил, уж ночь, поздно, а сдавать нужно совсем скоро.

Ночь ночью, но это зачем?

int* size = malloc(sizeof(int));

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Ну как зачем, выделяем память под указатель, ровно на один элемент. А сам указатель я стал использовать от безысходности, потому что не мог понять почему не работает. В итоге той ночью написал что требовалось. Если интересно, вот конечная программа:

#include <stdio.h>
#include <stdlib.h>
#include <sys/unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
 
int cmp (int* a, int* b)
{
   return *a > *b;
}
 
int main(void) 
{
    int clientPipe[2];
    pipe(clientPipe);
    int sortPipe[2];
    pipe(sortPipe);
    int size;
    pid_t childpid;
    int* rarray;
 
    int task = 0; // Set task to Client
    if ((childpid = fork()) == -1) {
        perror("fork");
        exit(1);
    } else if (childpid == 0 && task == 0) {
        /* Client */
 
        close(clientPipe[0]);
 
        scanf("%d", &size);
        rarray = malloc(sizeof(int) * size);
 
        write(clientPipe[1], &size, sizeof(int));
        time_t rawtime;
        srand(rawtime);
        for (int i = 0; i < size; i++)
            rarray[i] = rand();
 
        for (int i = 0; i < size; i++)
            printf("%d\n", rarray[i]);
 
        for (int i = 0; i < size; i++)        
            write(clientPipe[1], rarray+i, sizeof(int));
 
        exit(0);
    } else {
        /* Server */
 
        close(clientPipe[1]);
        int wstatus;
        wait(&wstatus);
 
        read(clientPipe[0], &size, sizeof(int));
        rarray = malloc(sizeof(int) * size);
        for (int i = 0; i < size; i++)
            read(clientPipe[0], rarray+i, sizeof(int));
 
    }
 
    task = 1; // Set task to Sort
    if ((childpid = fork()) == -1) {
        perror("fork");
        exit(1);
    } else if (childpid == 0 && task == 1) {
        /* Sort */
 
        close(sortPipe[0]);
 
        qsort(rarray, size, sizeof(int), cmp);
        printf("\n");
 
        for (int i = 0; i < size; i++)        
            write(sortPipe[1], rarray+i, sizeof(int));
 
        for (int i = 0; i < size; i++)
            printf("%d\n", rarray[i]);
 
        exit(0);
    } else {
        /* Server */
        close(sortPipe[1]);
        int wstatus;
        wait(&wstatus);
 
        for (int i = 0; i < size; i++)
            read(clientPipe[0], rarray+i, sizeof(int));
 
    }
 
    return(0);
}

zoroaster ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.