2016-07-22 195 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); 
    }