如何使用父进程和两个子进程将字符串写入文件?

时间:2018-05-15 09:28:09

标签: c unix process fork

我正试图解决这个问题,但我不能。

这是一个简短的描述:

  

我们有一个父有两个子进程(child_a,child_b)和N个字符串。

     

当前数据:data [i](0 ... N)

     
      
  1. Parent启动并等待来自child_b的信号。 Child_a正在等待。
  2.   
  3. Child_b向父母发送信号并等待数据。
  4.   
  5. 父将数据[i]写入管道并等待
  6.   
  7. Child_b从pipe和printf()读取data [i]。然后等待Child_a
  8.   
  9. Child_a生成一个随机数(1-5之间)并写入管道。
  10.   
  11. Child_b从管道读取rand并发送给Parent。
  12.   
  13. 父母将“data [i] - rand”写入文件。
  14.   
  15. 从下一个数据开始......
  16.   

这是我的代码:

FILE *fp2;
fp2 = fopen("bill.dat" , "a");

pid_t child_a, child_b;
int pipefd_a[2], pipefd_b[2];
char msg[100];
char sleep_time[10];

int stat;

signal(SIGUSR1, handler);
signal(SIGUSR2, handler);

if(pipe(pipefd_a) == -1 || pipe(pipefd_b) == -1){
    perror("Error\n");
    exit(EXIT_FAILURE);
}

int i;
for(i = 0; i < n; i++){

    child_a = fork();

    if(child_a < 0){
        perror("Error\n");
    }

    if(child_a == 0){
        sleep(1);
        printf("Child_a-----\n");
        srand(time(NULL));
        int r = rand()%5+1;
        char rand[2];
        sprintf(rand, "%d", r);
        printf("Child_a rand: %s\n", rand);
        write(pipefd_b[1], rand, strlen(rand)+1);
        printf("Child_a end-----\n");
        exit(0);
    }
    else{
        child_b = fork();

        if(child_b == 0){
            printf("Child_b sends a signal to parent\n");
            kill(getppid(), SIGUSR1);
            close(pipefd_a[1]);
            read(pipefd_a[0], msg, sizeof(msg));
            close(pipefd_a[0]);
            printf("Child_b reads from pipe (from parent): %s\n", msg);
            kill(child_a, SIGUSR2);
            sleep(2);
            read(pipefd_b[0], sleep_time, 10);
            printf("Child_b reads from pipe (from child_a): %s\n", sleep_time);
            fflush(NULL);
            write(pipefd_b[1], sleep_time, sizeof(sleep_time));
            close(pipefd_b[1]);
            printf("Child_b end-----\n");
            exit(0);

        }
        printf("============== %d ============== \n", i);
        printf("Parent waiting for signal...\n");
        pause();
        printf("Signal received\n");
        printf("Parent write into pipe\n");
        close(pipefd_a[0]);
        write(pipefd_a[1], data[i].address, 100);
        kill(child_b, SIGUSR2);
        waitpid(child_b, &stat, 0);
        read(pipefd_b[0], msg, sizeof(msg));
        fprintf(fp2, "%s - %s\n", data[i].address, msg);
        printf("Parent writes into file: %s\n", msg);
    }

}
fclose(fp2);

和我的输出(n = 2):

  • data1 - 1
  • data1 - 1
  • data1 - 1
  • data2 - 3

文件中总有2 ^ n行。 赋值需要两个子进程来实现这一点,我怀疑问题是循环中的“fork()”,但不明白我做错了什么。

1 个答案:

答案 0 :(得分:1)

第一个问题是您将流程创建置于for循环中。 这就是你获得2n行的原因。如果你想读取一些数据表单文件N次,你就不能进行N次处理。

第二件事你需要3个管道来完成工作。管道是单向的,意味着一个进程只能写入管道而另一个进程只能读取它。一端用于写入,另一端用于读取,因此必须关闭未使用的描述符!

    当父将data [i]写入管道并且child_b读取时,使用
  • 第一个管道
  • 当child_a将随机数写入管道并且child_b读取
  • 时,使用
  • 第二个管道
  • 当child_b写入管道并且父级执行读取时使用第三个管道

如果你能写完整个程序,我会更容易理解它并帮助你。 这是我试图做这项工作的骨架

int pipe_parent_to_childB[2], pipe_childB_to_parent[2], pipe_childA_to_childB;

if(pipe(pipe_parent_to_childB) == -1 || pipe(pipe_childB_to_parent) == -1 ||pipe(pipe_childA_to_childB) == -1)
{
            perror("Error\n");
            exit(EXIT_FAILURE);
}

//close read end because parent will write to pipe
close(pipe_parent_to_childB[0]);

switch(fork()) //create child b
{
    case -1:
        //error
    case 0:
        //now you are in child_b
        close(pipe_parent_to_childB[1]);
        close(pipe_childA_to_childB[1]);

        //perform some action


    default:
        break;
        }
}
switch(fork()) //crete child a
{
     case -1:
                //error
     case 0:
                //now you are in child_a
                close(pipe_childA_to_childB[0]);
                //perform some action

     default:
         break;


}

//here you are in parent process again. Send signals, wait for signals and write to pipe here
//from parent you send some data through pipe to process child_b N times
//after this you close write end of the pipe descriptor.