简体   繁体   English

无法使用c中的多个管道从进程读取消息

[英]Cant read messages from processes using multiple pipes in c

Im creating pipes for multiple children. 我正在为多个孩子创建管道。 The code catches a signal fro the keyboard and then the child should sent a message to the father with its result. 该代码从键盘捕获了一个信号,然后孩子应该向父亲发送一条消息及其结果。 The handling of the signal works fine but i cant sent the result to the father. 信号的处理效果很好,但我无法将结果发送给父亲。 I am i doing something wrong here? 我在这里做错了吗?

The code of the father process is : 父进程的代码是:

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

pid_t *childs; //array for storing childs pids
int number_of_childs;//variable for the number of childs
int exit_count=0;
int *fd;

/*Handler for the SIGINT signal*/

void control_handler(int sig)
{
if (sig==SIGINT){

    int j,bytes;
    char message[512];
    /*Sending SIGUSR1*/

    for (j=0;j<number_of_childs;j++)
    {
    kill(childs[j],SIGUSR1);
    }

    /*Reading from PIPES*/

    for (j=0;j<number_of_childs;j++)
    {   
    close(fd[(2*j)+1]);  
    bytes = read(fd[(2*j)], message, sizeof(message));
    printf("Read from: %s\n",message);
    close(fd[2*j]);
    }
}

if (sig==SIGUSR2)
{
exit_count++;
}

}

main (int argc,char *argv[]){

int i,child_status;
char cast[512];
char cast2[512];
char cast3[512];
int pid;
number_of_childs=atoi(argv[1]);

signal(SIGINT,control_handler);
signal(SIGUSR2,control_handler);

/*Creating array for children pipes*/
fd=(int*)malloc((2*number_of_childs)*sizeof(int));


/*array that holds the pids for every child used in sending signals*/
childs=malloc(number_of_childs*sizeof (pid_t));



for (i=0;i<number_of_childs;i++){
pid=fork();
    /*Create pipes to communicate with all children*/

    if(pipe(fd+(2*i))==-1)
    {
    perror("pipe");exit(1);
    }

    /*Fathers code goes here*/

    if(pid!=0)
        {
        printf("Parent process: PID= %d,PPID=%d, CPID=%d \n",getpid(),getppid(),pid);
        childs[i]=pid; // Keep all your childs in an array
        printf("Child:%d\n",childs[i]); 
        }

    /*If you are a child*/

        else 
        {
        /*Change the code for the childs and set the time of execution*/
        sprintf(cast,"%d",i+1); // make the time char
        sprintf(cast2,"%d",(2*i)+1);    //make the pipe char
        sprintf(cast3,"%d",number_of_childs);   
        execl("./Child.out","",cast,cast2,cast3,NULL);
        }
    }   
        /*Father should never terminate*/               
        while (exit_count!=number_of_childs);
        printf("Father pospastex!!\n");

}

the code for the child children is : 孩子的代码是:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h> 
#include <string.h>
#define WRITE 0
#define READ 1


/*Global declerations*/

int alarmflag=0;
double result=0;
int count=0;
int global_pipe;
int *fd;

/*Handler for the alarm and SIGUSR1 signal*/
void signal_handler (int sig)
{

if(sig==SIGALRM)
{
printf("Im child with pid:%d im going to die my value is %lf \n",getpid(),result);
alarmflag=1;
}

if(sig==SIGUSR1)
{
count++;
char message[512];

    if(count==1)
    {
    close(fd[global_pipe-1]);
    sprintf(message,"%d,%lf",getpid(),result);
    write(fd[global_pipe],message,strlen(message)+1);
    close(fd[global_pipe]); 
    //printf("PID:%d report: %lf\n",getpid(),result);
    }
    if(count==2)
    {
    close(fd[global_pipe-1]);
    sprintf(message,"%d,%lf",getpid(),result);
    write(fd[global_pipe],message,strlen(message)+1);
    close(fd[global_pipe]); 
    //printf("PID:%d report2 : %lf\n",getpid(),result);
    //kill(getppid(),SIGUSR2);
    //exit(0);
    }
}
if(sig==SIGINT)
{
/*Do nothing*/ 
}

}


double p_calculation ()
{
 int i=2;
 result=3;
 double prosimo=-1;

 while(!alarmflag)
    {
 prosimo=prosimo*(-1);
 result=result+(prosimo*(4/((double)i*((double)i+1)*((double)i+2))));
 i=i+2;
    }

}

main(int argc,char *argv[])
{
int pipe;
int size_fd;

size_fd=(atoi(argv[3]));
pipe=(atoi(argv[2]));
global_pipe=pipe;

fd=(int*)malloc(size_fd*sizeof(int));

/*handling signals*/
signal(SIGALRM,signal_handler);
signal(SIGUSR1,signal_handler);
signal(SIGINT,signal_handler);

/*Notify for execution time*/
printf("PID : %d with PPID : %d executing for %d seconds \n",getpid(),getppid(),atoi(argv[1]));
//printf("pipe:%d\n",pipe);
/*end this after the value passed as argument*/
alarm(atoi(argv[1]));
p_calculation();

/*Notify for finish*/

printf("Done!!!\n");

}

There are a number of problems related to your pipes: 与您的管道有关的问题很多:

  • you call pipe AFTER you call fork , so you end up with two independent pipes (one in the child and one in the parent). 您在调用fork之后调用pipe ,因此最终得到两个独立的管道(一个在子管道中,一个在父管道中)。 The parent listens to the one it creates (and noone is writing to), so it never sees anything. 父级会聆听它创建的内容(并且没有人在写),因此它永远不会看到任何内容。

  • you pass the index in your global fd array to the child rather than the file descriptor of the pipe. 您将全局fd数组中的索引传递给子级,而不是传递给管道的文件描述符。 The child has its own global fd array that contains random garbage, so you are essentially writing to a random file descriptor rather than the pipe. 该子项有其自己的全局fd数组,其中包含随机垃圾,因此您实际上是在写随机文件描述符,而不是管道。

  • you don't close the unneeded pipe ends in the various processes they exist in, so you cna never reliably get EOFs 您不会在它们存在的各种过程中关闭不需要的管道末端,因此您永远无法可靠地获得EOF

If you search for pipe+child here on stackoverflow, you'll see a large number of questions with example code trying to do things similar to what you are doing -- you may find it useful to read through those questions and answers. 如果您在此处通过stackoverflow搜索pipe + child ,您将看到大量问题,这些示例代码试图做与您正在做的事情类似的示例,您可能会发现通读这些问题和答案很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM