связь между дочерними и родительскими процессами в C linux: родительский процесс не блокируется

Я хочу, чтобы родительские и дочерние процессы взаимодействовали в C linux с помощью каналов. Сначала я хочу, чтобы родитель передал строку, а затем ребенок подтвердил ее. Я создал два файловых дескриптора. один для родительского к дочернему, т.е. readpipe и другой writepipe для наоборот. Проблема в том, что он не принимает мои данные в качестве входных данных. Также я хочу, чтобы операторы printf, такие как «Введите ваши данные», печатались один раз, но поскольку после разветвления есть два процесса, поэтому они отображаются дважды. Есть альтернатива этому??

 //readpipe[0] = child read
 //readpipe[1]= parent write

 //writepipe[0]=parent read
 //writepipe[1]=child write

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

 int main(void)
 {
     pid_t pid;
     int r;
    /* Hope this is big enough. */
     char buf[1024];
     char cp[50];
     char ans;
     int readpipe[2];
     int writepipe[2];
     int a;
     int b;
     a=pipe(readpipe);
     b=pipe(writepipe);
     if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
     if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }

     printf("\nSEND SOMETHING TO CHILD PROCESS\t");
     scanf(" %c",&ans);
     pid=fork();
     if(pid==-1)
     {
         printf("pid:main");
         exit(1);
     }

     while(ans=='y' || ans=='Y')
     {
        printf("\nEnter data\t"); //printed twice
        fgets(cp, 50, stdin);     //not taking data
        printf("\n%s",cp);        
        if(pid==0)
        { //CHILD PROCESS
            close(readpipe[1]);
            close(writepipe[0]);
            read(readpipe[0],buf,sizeof(buf));
            printf("\nSENT\n %s",buf);
            write(writepipe[1],cp,strlen(cp)+1);
        }
        else
        { //PARENT PROCESS
            close(readpipe[0]);
            close(writepipe[1]);
            write(readpipe[1],cp,strlen(cp)+1);
            read(writepipe[0],buf,sizeof(buf));
            printf("\nRECEIVED\n %s",buf);
        }
        printf("\nSEND SOMETHING TO CHILD PROCESS\t");
        scanf(" %c",&ans);
   }
  close(readpipe[1]);
  close(writepipe[0]);
  close(readpipe[0]);
  close(writepipe[1]);

 return 0;
}

Спасибо :)


person user3436838    schedule 19.03.2014    source источник
comment
Просто предложение. Не пытайтесь читать из канала, который вы только что закрыли. close(writepipe[0]), а затем read(writepipe[0],ch1,sizeof(ch1));... не получится так горячо.   -  person WhozCraig    schedule 19.03.2014
comment
Вы можете найти что-то вроде этого более простым для понимания, особенно в борьбе с мнемониками, такими как readpipe и writepipe.   -  person WhozCraig    schedule 19.03.2014
comment
Спасибо @WhozCraig. Я сделал некоторые изменения в своем коде. Еще есть 2 проблемы. Не могли бы вы мне помочь? Большое спасибо :)   -  person user3436838    schedule 19.03.2014


Ответы (1)


В вашем коде есть несколько проблем:

1.

close(writepipe[1]);

Вы не должны закрывать дескриптор файла, который вам нужен позже.

2.

read(readpipe[0],ch,sizeof(ch));

ch это NULL, что означает, что вы не выделили место для его указания.

3.

ch1="YES";
write(writepipe[1],ch1,sizeof(ch1));

Вы должны использовать strlen(ch)+1 вместо sizeof(ch), чтобы узнать, сколько байтов нужно записать.

4.

В вашем коде для родительского процесса есть аналогичные проблемы.


Вот фиксированная версия, основанная на коде в этом вопросе:

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

int main(void)
{
    pid_t pid;
    int r;
    /* Hope this is big enough. */
    char buf[1024];
    char *cp;

    int readpipe[2];
    int writepipe[2];
    int a;
    int b;
    a=pipe(readpipe);
    b=pipe(writepipe);
    // check a and b

    pid=fork();
    // check pid

    if(pid==0)
    { //CHILD PROCESS
        close(readpipe[1]);
        close(writepipe[0]);
        read(readpipe[0],buf,sizeof(buf));
        printf("\nREAD = %s",buf);
        close(readpipe[0]);
        cp="YES\n";
        write(writepipe[1],cp,strlen(cp)+1);
        close(writepipe[1]);
    }
    else
    { //PARENT PROCESS
        close(readpipe[0]);
        close(writepipe[1]);
        cp="HI!! YOU THERE";
        write(readpipe[1],cp,strlen(cp)+1);
        close(readpipe[1]);
        read(writepipe[0],buf,sizeof(buf));
        printf("\nACK RECEIVED %s",buf);
        close(writepipe[0]);
    }
    return 0;
}
person Lee Duhem    schedule 19.03.2014
comment
Большое спасибо. Это было действительно очень полезно..:) - person user3436838; 19.03.2014
comment
Я сделал некоторые изменения. И снова в проблеме. Не могли бы вы проверить это - person user3436838; 19.03.2014
comment
@user3436838 user3436838 Этот printf("Enter data\n"); fgets(cp, 50, stdin); будет выполняться как родительским, так и дочерним процессами. Это главная проблема вашего нового кода. - person Lee Duhem; 19.03.2014