使用switch语句分叉两个进程

时间:2017-06-01 01:45:50

标签: c linux posix

我正在参加C课程的介绍,我对第一次任务感到有点难过。我们的任务是创建父进程和两个子进程。到目前为止,文本向我们展示的所有示例都涉及具有一个父项和一个子项的switch语句。我对如何将其转换为一个父进程和两个子进程感到困惑。以下是我到目前为止的情况:

#include <stdio.h>

int main() {
    int i, pid, status;
    pid = fork();
    switch(pid) {
    case -1:
        /* An error has occurred */
        printf("Fork Error");
        break;
    case 0:
        /* This code is executed by the first parent */
        printf("First child process is born, my pid is %d\n", getpid());
        printf("First child parent process is %d\n", getppid());
        for (i=1; i<=10; i++)
            printf("First child process, iteration: %d\n", i);
        printf("First child dies quietly.\n");
        break;
    default:
        /* This code is executed by the parent process */
        printf("Parent process is born, my pid is %d\n", getpid());
        wait(&status);
        printf("Parent process dies quietly.\n");
    }
}

这适用于这一过程:

Parent process is born, my pid is 10850
First child process is born, my pid is 10851
First child parent process is 10850
First child process, iteration: 1
First child process, iteration: 2
First child process, iteration: 3
First child process, iteration: 4
First child process, iteration: 5
First child process, iteration: 6
First child process, iteration: 7
First child process, iteration: 8
First child process, iteration: 9
First child process, iteration: 10
First child dies quietly.
Parent process dies quietly.

基本上我只需要用第二个过程做同样的事情......比如:

printf("Second child process is born, my pid is %d\n", getpid());
printf("Second child parent process is %d\n", getppid());
for (k=1; k<=10; k++)
    printf("Second child process, iteration: %d\n", i);
printf("Second child dies quietly.\n");
break;

但我不知道如何从目前为止的目标到达那里。我接近这个正确的方法了吗?我应该使用更好的方法吗?非常感谢。

3 个答案:

答案 0 :(得分:3)

有一般规则。当您使用fork(2)时,您应该始终处理以下三个案例

  1. fork给出0,您在孩子过程中
  2. fork给出了肯定的pid_t,您在进程中
  3. fork 失败并给出-1
  4. 人们(新手)有时会忘记最后(失败)的情况。但它确实发生了,您可以通过在祖父进程中使用setrlimit(2)RLIMIT_NPROC来轻松测试该情况,以降低进程的限制,通常祖父进程是您的shell(例如,使用ulimit Bash builtin-u)。

    现在,如何处理这三种情况是编码风格的问题。您可以使用switch,但可以使用两个if。您的代码使用switch,这是正确的。

    作为一般规则,大多数system calls(在syscalls(2)中列出)可能会失败,您几乎总是需要处理失败案例(请参阅errno(3)并使用perror(3) )。

    另请阅读Advanced Linux Programming(可免费下载)。

      

    我对如何将其转换为一个父进程和两个子进程感到有点困惑。

    fork系统调用正在创建(成功时)一个子进程。因此,如果您需要两个孩子,您应该连续两次调用它(并在两次调用中测试失败)。如果你需要一个孩子和一个大孩子,你应该只在第一个给出0时进行第二个fork。当然你需要保持两个(成功和积极)pid_t -e.g.在两个变量中 - 由您对fork的两次调用返回。

    为了避免zombie processes,每个成功的fork都应该稍后进行等待系统调用(例如waitpid(2)waitwait4(2)wait3 )。在那里你做的那个等待取决于你是否想让两个孩子同时跑步。但是,每个成功的fork都应该有相应的成功wait来电。

    如果您希望异步通知有关子流程更改的通知,请另请阅读signal(7)(和signal-safety(7)SIGCHLD - 特别是终止。一种常见的方法是安装一个SIGCHLD信号处理程序(例如使用sigaction(2)或旧signal(2)),它只设置一些全局volatile sigatomic_t标志并测试然后在方便的时候清除该标志放在您的代码中(例如,使用event loop在某些poll(2)中)。

    注意:请注意,fork不是关于C编程(fork > C11标准n1570或其前身C99中定义的$FQDN = ('abc.xyz.me.com', 'def.me.com', 'ghi.sub.new.com', 'jkl.sup.old.com') ForEach ($Domain in $FQDN) { write-host ($Domain.split(".")[-2]) } {3}})。这是POSIX和Linux的事情。 Windows或z/OSArduino微控制器本身不具备该功能,但可在某些标准C中进行编程。

答案 1 :(得分:2)

您可以将fork和switch case放在循环中,以便它可以分叉多个进程,如下所示:

编辑:您可以删除if条件以在每个分支后调用wait,或者如果您想要启动所有子代然后等待它们终止,则在每次迭代中您都可以收集每个子代的pid (在父进程中,即在默认切换情况下)在数组中,在最后一次迭代中,在循环中调用waitpid(对于每个pid)以确保每个子进程已退出

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
    int i, pid, status;
    int j = 0;
    int numChildren = 2;/*Change it to fork any number of children*/
    for(j = 0;j< numChildren;j++)
    {
            pid = fork();
            switch(pid) {
            case -1:
                /* An error has occurred */
                printf("Fork Error");
                break;
            case 0:
                /* This code is executed by the first parent */
                printf("First child process is born, my pid is %d\n", getpid());
                printf("First child parent process is %d\n", getppid());
                for (i=1; i<=10; i++)
                    printf("First child process, iteration: %d\n", i);
                printf("First child dies quietly.\n");
                exit(0);/*Otherwise it will fork its own child*/
                break;
            default:
                /* This code is executed by the parent process */
                printf("Parent process is born, my pid is %d\n", getpid());
                if(j == (numChildren - 1))/*You can remove this condition to wait after each fork*/
                {
                wait(&status);
                printf("Parent process dies quietly.\n");
                }
            }
        }
}

答案 2 :(得分:-1)

要生成2个孩子,请调用fork()2x。因此,使用2个不同的变量调用fork,然后等待它们。