两个进程之间的FIFO通信c

时间:2016-10-24 03:59:29

标签: c ubuntu exec fifo

我正在试图让两个进程通过命名管道进行通信。就像这样,首先我的过程" prac"这些孩子通过信号(下面的代码中的scanf)接收到他们不得不接受一个" execl(dadesPrac)"谁只需要通过FIFO写一个字符串给他的父母。问题是,似乎它在FIFO中被卡住了。  我甚至不能通过终端看到消息:

" printf("我终于写了%s \ n",缓冲区);"

写作的过程得到了"名称"通过execl prevoiusly的参数说明的fifo,它是这样的:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX_BUF 64
#include <string.h>
#include <errno.h>
#include <signal.h>
int main(int argc, char **argv){
    int fd;
    char buffer[MAX_BUF] = "";
    char aux[MAX_BUF] = "";
    int MaxTemp;
    printf("%s , %s , %s \n",argv[0],argv[1],argv[2]);
    if(argc == 3){
        srand(time(NULL));
        MaxTemp = (rand() % 50) + 10;
        printf("I'M IN EXEC\n");
        sprintf(aux,"%i",MaxTemp);
        printf(" MAXTEMP  %s\n",aux);
        strcat(buffer,aux);

        strcat(buffer,argv[2]);
        printf("what i'm gonna write is %s\n",buffer);
        fd = open(argv[1],O_WRONLY);    
        write(fd, buffer, sizeof(MAX_BUF));
        printf("i finally wrote %s\n",buffer);
        close(fd);
        //unlink(argv[1]);

    }else{
        perror(" number of parameters incorrect");  
    }



printf("i'm gonna exit\n");
_exit(0);
}

流程实践的代码如下:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX_BUF 64
#include <string.h>
#include <errno.h>
#include <signal.h>

int senyal = 0;

void empezar(int signum){
    senyal++;
}


void make_fifo(char * myfifo){
    /* crea l'arxiu fifo en cas de que ja no existeixi previament*/
    int m;

    if ((m = mkfifo(myfifo, 0666)) < 0){
        if (errno != EEXIST){
            perror ("mkfifo");
        }
    }
}
int main(int argc,char **argv) {

    int m;
    int pid11;
    int fd, pid1,pid2,pid3,auxint,auxint2,status;
    char * npipe1 = "/tmp/npipe1";
    char buf[MAX_BUF];
    char aux[MAX_BUF];
    pid1 = fork();
    if(pid1 == 0){

        //child1
        make_fifo(npipe1);
        pid11 = fork();

        if(pid11 == 0){
            //grandson1
            printf("inside grandson \n");
            signal(SIGUSR1,empezar);
            while(!senyal){
                printf("im in the while\n");
                sleep(1);       
            }
            printf("i'm out of the  while\n");
            sprintf(aux,"%i",getpid());
        execl("./dadesPrac","dadesPrac",npipe1,aux,NULL);


        }
        printf("almost waitpid\n"); 
        wait(NULL);
        printf("after waitpid\n");
        fd = open(npipe1,O_RDONLY);
        read(fd, buf, sizeof(MAX_BUF));
        close(fd);
        printf("%s",buf);

        //do sql stuff
    }

printf("i'm in dad \n");
scanf("%i",&auxint2);
kill(pid11,SIGUSR1);
wait(NULL);
  return 0;
}

我老实地输了,对不起可能的错误感到抱歉,而不是母语人士,所以很难清楚地解释自己。

1 个答案:

答案 0 :(得分:1)

我认为问题在于你做叉子和处理信号的方式。

第一次进行prac分叉时,您已将孩子的pid分配给pid1。 父(原始prac)然后调用scanf()并等待。

您的子进程(prac child)再次调用fork(),并将孙子的pid分配给pid11prac孙子。)

然后,您尝试使用父(原prac)将信号发送给孙子(pid11)。但是,父级没有孙子的正确pid,因为孙子是由子代码而不是父代创建的。父进程中的pid11仍然是其默认值,在代码中未定义。

因此,当您输入一些输入时,父项执行kill()函数,如果pid11的默认值为0,则表示将信号发送到具有相同进程组ID的所有进程(参考kill())。如果pid11不为0,则信号将发送到错误的进程。

此外,您只为孙子进程编写安装信号处理程序,因此父进程和子进程都被终止。因此没有人会读取FIFO。