0

複数の子供用のパイプを作成しています。コードはキーボードからの信号をキャッチし、子供はその結果を父親にメッセージで送信する必要があります。信号の処理は正常に機能しますが、結果を父に送信できません。私はここで何か間違ったことをしていますか?

親プロセスのコードは次のとおりです。

#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");

}

子 children のコードは次のとおりです。

#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");

}
4

1 に答える 1

0

パイプに関連する多くの問題があります。

  • を呼び出した後pipeに呼び出すforkため、2 つの独立したパイプ (子に 1 つ、親に 1 つ) が作成されます。親は自分が作成したものをリッスンする (そして誰も書き込みを行っていない) ため、何も表示されません。

  • fdパイプのファイル記述子ではなく、グローバル配列のインデックスを子に渡します。子には、ランダムなガベージを含む独自のグローバルfd配列があるため、基本的にパイプではなくランダムなファイル記述子に書き込みます。

  • それらが存在するさまざまなプロセスで不要なパイプの端を閉じないので、EOFを確実に取得することはできません

ここでstackoverflowでpipe+childを検索すると、あなたがしていることと同様のことをしようとしているサンプルコードを含む多数の質問が表示されます.これらの質問と回答を読むと役立つ場合があります.

于 2012-10-01T17:56:25.353 に答える