2016-07-22 137 views
-1

child_filter必须从pipefd中读取值并将其写入命名管道中。 问题是,如果我尝试取消注释注释[3](命名管道的打开),函数将不会打印值,它似乎卡在read()调用上。相反,如果我不打开fifo管道,它的工作原理。 我需要命名管道为其他东西。 我应该修改什么?也许管道和命名管道冲突一起使用它们? 谢谢。在C中使用管道的命名管道块子进程

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

#define FIFONAME "./my-fgrep-named-pipe" 

typedef struct{ 
    int i; 
    int v; 
    int word; 
    int filename; 
    char word_string[250]; 
    char filename_string[250]; 
}parameters; 

int pipefd[2]; 
void child_reader(parameters params){ 
    FILE* fp; 
    char *line = NULL; 
    size_t len = 0; 
    ssize_t read; 

    if(params.filename==0) 
     fp = stdin; 
    else 
     fp = fopen(params.filename_string, "r"); 

    close(pipefd[0]);   /* Close unused read end */ 
    if (fp != NULL){ 
     while ((read = getline(&line, &len, fp)) != -1) { 
      //printf("Retrieved line of length %zu :\n", read); 
      //printf("%s", line); 
      write(pipefd[1], line, strlen(line)); 
     } 
     fclose(fp); 
    } 
    free(line); 
    printf("child reader > end\n"); 
    exit(0); 
} 
void child_filter(parameters params){ 
    char c; 
    char temp[250]; 
    int i=0; 
    char *temp2; 
    int fifofd; 
    close(pipefd[1]);   /* Close unused write pipe end */ 
    printf("read from pipe\n"); 
    if((fifofd = open(FIFONAME, O_WRONLY)) == -1) printf("Error WW\n"); 
    while (read(pipefd[0], &c, 1) > 0){ 
     if (c == '\n' || c == '\r'){ 
      temp[i] = '\n'; 
      if(i>0){ 
       temp2=strtok(temp, "\n"); 
       //temp2[i] = '\n'; 
      // printf("[%s]\n", temp2); 
       write(fifofd, temp2, strlen(temp2)); 
      }i=0; 
     } 
     else{ 
      temp[i] = c; 
      i++; 
     } 
    } 
    close(fifofd); 
    printf("child filter > end\n"); 
    exit(0); 

} 

void child_writer(parameters params){ 
    char c; 
    int fifofd; 

    char temp[250]; 
    int i=0; 
    char *temp2; 

    if((fifofd = open(FIFONAME, O_RDONLY)) == -1) printf("Error RR\n"); 
    while (read(fifofd, &c, 1) > 0){ 
     printf("entry > [%c] \n", c); 

    } 
    printf("exit-------------\n"); 
    close(fifofd); 
    unlink(FIFONAME); 
    exit(0); 
} 

int main(int argc, char *argv[]){ 
    char* temp1; 
    parameters params; 
    int forkResult; 
    params.i=0; 
    params.v=0; 
    params.word=0; 
    params.filename=0; 
    int pid_r, pid_w, pid_f; 
    if(argc<2){ 
     printf("error\n"); 
     exit(0); 
    } 

    if(strcmp(argv[1],"-i") == 0) 
     params.i++; 
    if(strcmp(argv[1],"-v") == 0) 
     params.v++; 
    if(argc>2){ 
     if(strcmp(argv[2],"-i") == 0) 
      params.i++; 
     if(strcmp(argv[2],"-v") == 0) 
      params.v++; 
    } 
    if(params.i == 0 && params.v == 0){   
     params.word++; 
     strcpy(params.word_string, argv[1]); 
     if(argc>2){ 
      params.filename++; 
      strcpy(params.filename_string, argv[2]); 
     } 
    } 
    else if(params.i != 0 && params.v != 0){ 
     if(argc>3){ 
      params.word++; 
      strcpy(params.word_string, argv[3]); 
     } 
     if(argc>4){ 
      params.filename++; 
      strcpy(params.filename_string, argv[4]); 
     } 
    } 
    else{    
     if(argc>2){ 
      params.word++; 
      strcpy(params.word_string, argv[2]); 
     } 
     if(argc>3){ 
      params.filename++; 
      strcpy(params.filename_string, argv[3]); 
     } 
    } 

    printf("Result: i[%d], v[%d], name[%d], filename[%d]\n", params.i, params.v, params.word, params.filename); 

    if(params.word==0){ 
     printf("Error X\n"); 
     exit(0); 
    } 


    if (pipe(pipefd) == -1) { 
     printf("pipe error\n"); 
     exit(0); 
    } 
    unlink(FIFONAME); 
    if(mkfifo(FIFONAME, 0666) != 0) printf("Error fifo1\n"); 

    if((pid_r=fork()) == 0){ 

     child_reader(params); 
    } 
    if((pid_f=fork()) == 0){ 
     child_filter(params); 
    } 
    if((pid_w=fork()) == 0){ 
     child_writer(params); 
    } 
    waitpid(pid_r, NULL, 0); 
    printf("Reader finished\n"); 
    close(pipefd[1]); 

    waitpid(pid_f, NULL, 0); 
    close(pipefd[0]); 

    printf("filter finished\n"); 

    waitpid(pid_w, NULL, 0); 
    printf("Done!\n"); 
    exit(0); 


} 
+0

您*设置'pipefd'的地方?你能否请尝试创建一个[最小,完整和可验证示例](http://stackoverflow.com/help/mcve)并向我们展示?包括你如何初始化'pipefd'并调用这个函数? –

+0

也不是说,如果成功,'open'调用将返回'0'是不太可能的。请尝试检查“-1”。 –

回答

1

如果你打开一个命名管道进行书写,那么它会阻塞,直到另一端打开阅读。这是一种预期的行为。

我需要命名管道的其他东西

好吧,如果没有一个从管道读取,然后你可以用管道写到底什么其他的东西?所以,你必须确保管道中有读者,或者延迟打开管道,直到有人准备读取管道。另一种选择是使用O_RDWR打开。

+0

好的,这是问题。谢谢! 并关闭它?我必须先关闭阅读器?因为现在该过程读取并打印管道的每个值(FIFO),但不会完成... –

0

问题是叉子的文件描述符,所以他们仍然打开。 由于这个原因,子进程无法完成。 固定代码:

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

    #define FIFONAME "./my-fgrep-named-pipe" 

    typedef struct{ 
    int i; 
    int v; 
    int word; 
    int filename; 
    char word_string[250]; 
    char filename_string[250]; 
    }parameters; 

    int pipefd[2]; 
    void child_reader(parameters params){ 
    FILE* fp; 
    char *line = NULL; 
    size_t len = 0; 
    ssize_t read; 
    if(params.filename==0) 
      fp = stdin; 
    else 
      fp = fopen(params.filename_string, "r"); 

    close(pipefd[0]);   /* Close unused read end */ 
    if (fp != NULL){ 
      while ((read = getline(&line, &len, fp)) != -1) { 
        //printf("Retrieved line of length %zu :\n", read); 
        //printf("%s", line); 
        write(pipefd[1], line, strlen(line)); 
      } 
      fclose(fp); 
    } 
    free(line); 
    close(pipefd[1]);   /* Close unused read end */ 
    printf("child reader > done\n"); 
    exit(0); 
    } 
    void child_filter(parameters params){ 
    char c; 
    char temp[250];  
    int i=0; 
    char *temp2; 
    int fifofd; 
    close(pipefd[1]);   /* Close unused write pipe end */ 

    if((fifofd = open(FIFONAME, O_WRONLY)) == -1) printf("Error fifoWW\n"); 
    printf("read from pipe\n"); 
    while (read(pipefd[0], &c, 1) > 0){  
      if (c == '\n' || c == '\r'){ 
        temp[i] = '\n'; 
        if(i>0){ 
          temp2=strtok(temp, "\n"); 
          //temp2[i] = '\n'; 
          //printf("[%s]\n", temp2); 
          write(fifofd, temp2, strlen(temp2)); //prima senza +1; 
        }i=0; 
      } 
      else{ 
        temp[i] = c; 
        i++; 
      } 
    } 
    close(fifofd); 
    close(pipefd[0]);  
    printf("child filter > done\n"); 
    exit(0); 

    } 

    void child_writer(parameters params){ 
    char c; 
    char temp[250];  
    int i=0; 
    char *temp2; 
    int size; 
    int fifofd; 
    if((fifofd = open(FIFONAME, O_RDONLY)) == -1) printf("Error fifoRR\n"); 
    do{ 
      printf("entry> [%c] \n", c); 
      size = read(fifofd, &c, 1); 
      printf("next size read> %d\n", size); 
    }while(size > 0); 
    close(fifofd); 
    printf("exit-------------\n"); 
    //unlink(FIFONAME); 
    exit(0); 
    } 

    int main(int argc, char *argv[]){ 
    char* temp1; 
    parameters params; 
    int esitoFork; 
    params.i=0; 
    params.v=0; 
    params.word=0; 
    params.filename=0; 
    int pid_r, pid_w, pid_f; 
    FILE *myfifo; 
    if(argc<2){ 
      printf("error \n"); 
      exit(0); 
    } 

    if(strcmp(argv[1],"-i") == 0) 
      params.i++; 
    if(strcmp(argv[1],"-v") == 0) 
      params.v++; 
    if(argc>2){ 
      if(strcmp(argv[2],"-i") == 0) 
        params.i++; 
      if(strcmp(argv[2],"-v") == 0) 
        params.v++; 
    } 
    if(params.i == 0 && params.v == 0){     // [3] ho il nome, [4] ho il filename 
      params.word++;  
      strcpy(params.word_string, argv[1]); 
      if(argc>2){ 
        params.filename++; 
        strcpy(params.filename_string, argv[2]); 
      } 
    } 
    else if(params.i != 0 && params.v != 0){  // [2] ho il nome, [3] ho il filename 
      if(argc>3){ 
        params.word++; 
        strcpy(params.word_string, argv[3]); 
      } 
      if(argc>4){ 
        params.filename++; 
        strcpy(params.filename_string, argv[4]); 
      } 
    } 
    else{        // [3] ho il nome, [4] ho il filename 
      if(argc>2){ 
        params.word++; 
        strcpy(params.word_string, argv[2]); 
      } 
      if(argc>3){ 
        params.filename++; 
        strcpy(params.filename_string, argv[3]); 
      } 
    } 

    printf("Result: i[%d], v[%d], nome[%d], filename[%d]\n", params.i, params.v, params.word, params.filename); 

    if(params.word==0){ 
      printf("Error syntax\n"); 
      exit(0); 
    } 


    if (pipe(pipefd) == -1) { 
      printf("pipe error\n"); 
      exit(0); 
    } 

    if(mkfifo(FIFONAME, 0666) != 0) printf("Error fifo\n"); 


    if((pid_r=fork()) == 0){ 

      child_reader(params); 
    } 
    if((pid_f=fork()) == 0){ 
      child_filter(params); 
    } 
    close(pipefd[0]); 
    close(pipefd[1]); 
    if((pid_w=fork()) == 0){ 
      child_writer(params); 
    } 
    waitpid(pid_r, NULL, 0); 
    printf("Reader finished\n"); 

    waitpid(pid_f, NULL, 0); 
    printf("filter finished\n"); 

    waitpid(pid_w, NULL, 0); 
    printf("Done!\n"); 
    unlink(FIFONAME); 
    exit(0); 
    }