0

2 つの名前のないパイプで作成した 2 つのプロセスがありますが、息子から父親にメッセージを送信できない理由がわかりません。父親は糸を受け取っていないようです。息子は正しい文字列を送信しています。目的地に届かないだけで、理由がわかりません... 説明してもらえますか?

#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <strings.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>

    #define max_chars_string 1000
    #define n_childs 2

    pid_t childs[n_childs];
    int channel[n_childs][2];

    void read_lines(char * filename, char (*pointer)[max_chars_string],int init_read,int n_lines);
    void get_strings_hash(char (*pointer_strings)[max_chars_string],char (*pointer_hashes)[max_chars_string],int total_lines);

    void worker(int mypipe,char filename[],int n_lines){ // meter as funcoes de ler passwords no filho
        int resources[2];// numero de linhas que cada processo tem de ler
        int i = 0;

        //definicao arrays
        char strings_hashes[n_lines][max_chars_string];//aray de string com as strings lidas do ficheiro
            char * pointer_strings = &strings_hashes[0][0];//ponteiro para o inicio do array das hashes

        read_lines(filename,strings_hashes,0,n_lines); // le as strings do ficheiro e passa para o array

        for(i = 0;i<n_lines;i++){
            printf("%s \n",strings_hashes[i]);
        }
        printf("[%d] My parent is: %d\n", getpid(), getppid());

        //open pipe to write and close pipe to read

        close(channel[mypipe][0]);
        i = 0;
        int incr = 0;
        while (i<n_lines) {
            printf("[Son] Password sent e  %s: \n",strings_hashes[incr]);
             write(channel[mypipe][1], strings_hashes[incr], strlen(strings_hashes[incr]));
             incr++;
             i++;
        }
        exit(0);
    }

    int main(int argc, char **argv)
    {
        char *filename;
        int status;//status do processos filho
        int resources[2];// numero de linhas que cada processo tem de ler
        int n_lines; //numero de linhas do ficheiro
        int i = 0;

          // Create a pipe
        filename = (char*)malloc(strlen(argv[1])*sizeof(char)+1);

        if(argc !=3){
            fprintf(stderr, "Usage : %s [text_file] [cores]",argv[0]);
            exit(0);
        }

        strcpy(filename,argv[1]);

        char get_file [strlen(filename)];
        strcpy(get_file,filename);

     // start the processes
       for(i = 0; i <atoi(argv[2]);i++){
            pipe(channel[i]);
            childs[i] = fork();

            if(childs[i] == -1){
               perror("Failed to fork");
               return 1;
           }
           if (childs[i] == 0)
           {
              worker(i,get_file,n_lines);
           }
           close(channel[i][1]);
       }

               i = 0;
               int k = 0;
               int fd;
               fd_set read_set;
               FD_ZERO(&read_set);
               char string_lida [30];

               // working father
               printf("[%d] I'm the father!\n", getpid());
               printf("[Father]orking ...\n");

                //unammed_pipes connection
                while(k<n_childs){

                    FD_SET(channel[0][0], &read_set);
                    for(i=0;i<n_childs;i++){
                            FD_SET(channel[i][0], &read_set);
                            if(fd<channel[i][0]){      fd=channel[i][0];
                            }
                        }

                    if(select(fd+1,&read_set,NULL,NULL,NULL)>0){
                        for(i=0;i<n_childs;i++){
                            if(FD_ISSET(channel[i][0], &read_set)){                    
                                read(channel[i][0],string_lida,strlen(string_lida));
                                printf("[Father]pipe %d - string lida:%s\n",i,string_lida);

                                k++;                 
                            }
                        }
                    }
                    fd=1;
                }
              //
              //waiting for childs ...
            for(i=0;i<n_childs;i++){
                wait(&status);
                printf("waiting for childs \n");
              }

      return 0;
    }  


    void get_strings_hash(char (*pointer_strings)[max_chars_string],char (*pointer_hashes)[max_chars_string],int total_lines)//vai ao array de strings e corta a parte de hash e mete num array
    {
        int i = 0;
        char *strings;
        char *hash;

        for(i = 0;i<total_lines;i++){
                strings = (char*)malloc(strlen(pointer_strings)*sizeof(char)+1);
                strcpy(strings,*pointer_strings);
                hash = (char*)malloc(strlen(pointer_strings)*sizeof(char)+1);
                find_hash(strings,hash);
                strcpy(*pointer_hashes,hash);
            pointer_hashes++;
            pointer_strings++;
        }

    }


    void read_lines(char * filename, char (*pointer)[max_chars_string],int init_read,int n_lines){ 
        FILE *fp;
        char str[max_chars_string];
        int i =0;

        if((fp = fopen(filename, "r"))==NULL) {
          printf("Cannot open file.\n");
          exit(1);
        }

        if(init_read>0 && init_read<=n_lines){
         for(i = 0;i<init_read;i++){
             fgets(str, sizeof str, fp);
           for(i = init_read;i<n_lines;i++){
               fgets(str, sizeof str, fp);
               strcpy(*pointer, str); //copia para a posicao actula do ponteiro
               pointer++;
           }
         }
        }
        if(init_read<=n_lines && init_read==0){
           for(i = init_read;i<n_lines;i++){
                fgets(str, sizeof str, fp);
               strcpy(*pointer, str); //copia para a posicao actula do ponteiro
               pointer++;
           }
         }


      fclose(fp);
    }
4

1 に答える 1

1

1 つの問題は次の行です。

read(channel[i][0],string_lida,strlen(string_lida));

初期化しないのでstring_lida、 はstrlen何かを返す可能性がありますが、0 を返す (文字列が空である) と推測しているため、何も読み取れません。sizeof(string_lida)代わりに欲しい。string_lida読み取りではそうしないため、文字列を手動で NUL 終端する必要があります。そのため、の戻り値をチェックして、read読み込まれた文字数 (または EOF かどうか) を確認する必要があります。

また、合計 n_childs 文字列が読み取られるのを待つだけです。各子が複数の文字列を送信すると、それらのほとんどを取得できません。

于 2012-10-12T23:29:35.177 に答える