【问题标题】:Trying to create 2 child processes and 1 grandchild that run in order尝试创建按顺序运行的 2 个子进程和 1 个孙子进程
【发布时间】:2017-11-09 19:05:09
【问题描述】:

所以我试图从第一个子进程中创建 2 个子进程和一个孙子进程。我试图运行第一个子进程,然后是孙子进程,然后是第二个子进程,当进程完成时,父进程调用 pid。我完全陷入困境 - 我有许多代码版本,但无法让它们以正确的顺序触发。任何帮助、建议或链接将不胜感激。

期望的输出是

-我是第一个孩子

----我是孙子

我是家长,第一个孩子的 pid 为 21505

-我是第一个孩子,孙子的pid是21506

-再试一次

--我是老二

-- -->第二个孩子:传输了 1317 个字节。

我又是家长了,第二个孩子的 pid 为 21507

父 - 子 21507 已完成

-再试一次

**** 应该在这里看到 lab4.c 文件的前 20 行

父母 - 其他孩子 21505 已完成

int main(int* argc, char* args[])
{
pid_t child1, child2, gchild; //process ids
child1 = fork();           //Create the two child processes
if (child1 == 0)
{ // parent
    child2 = fork();
    if (child2 == 0)
    { //parent
        printf("P: first child has pid %d\n", child1);
        printf("P: second child has pid %d\n", child2);

        pid_t wpid; // process id that is finished
        int status; //status code returned by process  
                    //Wait for all child processes to complete
        while ((wpid = wait(&status)) > 0)
        {
            if (wpid > 0)
            {
                printf("P: Child %d is done \n", wpid);
            }
        };

        exit(0); //exit main parent process
    }
    else
    {
        //Second process's code

        printf("SC: I am the second child.\n");
        int totalBytes = 0; //total number of bytes in the file we are going to read in
        char buffer[2056]; //file contents size 2056 bytes
        ssize_t read_bytes = 0; //Bytes from each chunk get placed here temporarily

        ///Read in file contents: home/common/lab_sourcefile
        int fd_in = open("/home/COIS/3380/lab4_sourcefile", O_RDONLY);//open the file
        do
        {
            //read the file chunk by chunk to the buffer
            read_bytes = read(fd_in, buffer, (size_t)2056);

            // End of file or error.
            if (read_bytes <= 0)
            {
                break; //done reading file
            }

            //Save the total number of bytes
            totalBytes = totalBytes + read_bytes;
        } while (1); //infinite loop until we are done reading the file

        //Write out contents to: lab4_file_copy
        char filepath[1024]; //temp path
        getcwd(filepath, sizeof(filepath)); //Get the current working directory
        strcat(filepath, "/lab4_file_copy"); //Tack on the filename
        int fd = open(filepath, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); //open the file. O_RDWR = read and write flag, O_CREAT = create if doesnt exist, S_* flags are permission flags from fstat 
        write(fd, buffer, strlen(buffer)); //write to the file

        close(fd_in);//close file we were reading
        close(fd); //close copy file

        // print out the number of bytes the file
        printf("SC: --> Second child: %d bytes transferred.\n", totalBytes);

        exit(0); //done kill second child process
    }
}
else
{
    //First child process

    printf("FC: I'm the first child.\n");

    //Create the granchild process
    gchild = fork();
    if (gchild == 0)
    {
        printf("GC: I am the grandchild.\n");

        sleep(3); //sleep for 3 seconds

        printf("GC: #### Output start ####\n");
        execlp("head", "head", "-n", "20", "l.c", NULL); //this should exit automatically
        printf("ERROR: execlp command failed\n");//This will only run if the execlp process fails
        exit(1); //FAILED!
    }
    else
    {
        //Output the granchild pid
        printf("FC: I am the first child, grandchild has pid %d\n", gchild);
        int grandchildStatus;
        //Wait for grandchild process to be done. Polling...
        while ((waitpid(gchild, &grandchildStatus, WNOHANG)) != gchild)
        {
            printf("FC: Try again\n");
            sleep(1);
        };
        printf("GC: #### Output end ####\n");
        //End of first child. Grandchild must have completed.

        exit(0); //Done. kill first child process
    }
}

}

【问题讨论】:

  • 如果您交换了第 3 行和第 4 行,您可以简单地在每次分叉后与 wait 调用同步。如果您希望它们保持原样,您将需要一个额外的同步机制。有很多可供选择:管道、信号、共享内存信号量等。随便挑吧。
  • 学习信号量。

标签: c process fork wait


【解决方案1】:

你的程序基本上有两个错误:

  • 最后else部分:

    您调用fork,因此fork 函数之后的所有内容都将在两个进程中执行。

    父母和第二个孩子将打印:“我是父母,第一个孩子有 pid...

    要解决此问题,您必须添加一个 if(child2 == 0)(在 else 块内)...

  • 指令顺序:

    当您启动子进程时,子进程将真正与父进程同时运行:

    如果一个进程打印出“Hello world.”而另一个进程打印出“This is a test.”,您可能会在屏幕上看到以下文本: “This Hello 是一个 世界。 test.”(或类似的)因为两个进程同时写入屏幕。

    您可以在子进程的父进程中使用waitpid 函数等待子进程完成,以确保子进程在父进程继续(打印出文本)之前完成。

    但是,如果您想首先在父进程中打印文本,则必须找到一种方法来停止子进程并等待父进程完成打印。

    例如,您可以使用raise(SIGSTOP); 来停止当前正在运行的进程。在另一个进程中使用kill(pid, SIGCONT); 继续等待的另一个进程pid

    child = fork();
    if(child == 0)
    {
        raise(SIGSTOP); /* Wait for the parent */
        /* Do something */
    }
    else
    {
        /* Do something */
        kill(child, SIGCONT); /* Tell the child to continue */
    }
    

...然而:正如 PSkocik 刚刚提到的那样,即使在这种情况下,您的程序也可能会挂起 - 所以这并不容易!

【讨论】:

  • 如果 SIGCONT 在 SIGSTOP 之前发送怎么办?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多