使用switch语句分叉两个进程 [英] Using switch statements to fork two processes

查看:134
本文介绍了使用switch语句分叉两个进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在介绍C课程,我对第一次作业有些困惑.我们的任务是创建一个父流程和两个子流程.到目前为止,文本向我们展示的所有示例都涉及带有一个父级和一个子级的switch语句.我对如何将其转换为一个父进程和两个子进程感到困惑.这是我到目前为止的内容:

I'm taking an intro to C course and I've become a bit stumped on the first assignment. We've been tasked with creating a parent processes and two child processes. All of the examples the text has shown us so far involve switch statements with one parent and one child. I'm a bit confused about how to translate this into one parent and two child processes. Here is what I have so far:

#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.

本质上,我只需要在第二个步骤中做同样的事情即可……

Essentially I just need to do the same thing with a second process... something like:

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;

但是我不确定目前为止如何到达那里.我要采用这种正确的方法吗?我应该使用更好的方法吗?非常感谢.

But I'm just not sure how to get there from what I have so far. Am I approaching this correct way? Is there a better method I should be using? Thanks so much.

推荐答案

有一条通用规则.使用叉子(2)时,您应该始终处理以下 3 个案例:

There is a general rule. When you use fork(2) you should always handle the three cases below:

  1. fork给出了0,表示您处于 child 进程
  2. fork给出了正数pid_t,您处于父级进程中
  3. fork 失败并给出-1
  1. fork gave 0, you are in the child process
  2. fork gave a positive pid_t, you are in the parent process
  3. fork failed and gave -1

人们(新手)有时会忘记最后一个(失败)的情况.但这确实发生了,您可以使用 setrlimit( 2)在您的祖父母进程中使用RLIMIT_NPROC来降低对进程的限制,通常该祖父母进程就是您的外壳程序(例如,使用

People (newbies) sometimes tend to forget the last (failure) case. But it does happen, and you might easily test that case by using setrlimit(2) with RLIMIT_NPROC in your grand-parent process to lower the limit on processes, often that grand-parent process is your shell (e.g. using ulimit Bash builtin with -u).

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

Now, how to handle the three cases is a matter of coding style. You can use switch but you can use two if. Your code uses a switch and is right to do so.

通常,大多数系统调用(在 errno(3)并使用 perror(3)).

As a general rule, most system calls (listed in syscalls(2)) can fail, and you almost always need to handle the failure case (see errno(3) and use perror(3)).

另请阅读 高级Linux编程 (可免费下载).

Read also Advanced Linux Programming (freely downloadable).

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

I'm a bit confused about how to translate this into one parent and two child processes.

fork系统调用正在成功创建一个完全一个子进程.因此,如果您需要两个孩子,则应连续调用两次(并且两次调用均测试失败).如果您需要一个孩子和一个孙子,则仅当第一个孩子为0时才应执行第二个fork.当然,您需要同时保持(成功和肯定)pid_t-e.g.在两个变量中-由您两次调用fork返回的.

The fork system call is creating (on success) exactly one child process. So if you need two children, you should call it twice (and test failure on both calls) in a row. If you need one child and one grand child, you should do the second fork only when the first one gave 0. Of course you need to keep both (successful and positive) pid_t -e.g. in two variables- returned by your two calls to fork.

为避免僵尸进程,每个成功的fork都应稍后调用其等待系统(例如 waitpid(2)wait wait4(2)wait3).等待的位置取决于您是否希望两个孩子同时运行.但是每个成功的fork都应该有一个相应的成功的wait调用.

To avoid zombie processes, every successful fork should later have its wait system call (e.g. waitpid(2) or wait or wait4(2) or wait3). Where you do that wait depends if you want to have both children running at the same time or not. But every successful fork should have a corresponding successful wait call.

还请阅读 signal(7)(和<关于SIGCHLD的href ="http://man7.org/linux/man-pages/man7/signal-safety.7.html" rel ="nofollow noreferrer">信号安全(7))如果您想异步收到有关子进程更改的通知-特别是终止.一种常见的方法是安装SIGCHLD信号处理程序(例如,使用 sigaction (2)或旧的 signal(2)),它只是设置一些全局volatile sigatomic_t标志并进行测试,然后在代码中的方便位置清除该标志(例如,在某些 poll(2)).

Read also signal(7) (and signal-safety(7)) about SIGCHLD if you want to be asynchronously notified about child processes change - notably termination. A common way is to install a SIGCHLD signal handler (e.g. using sigaction(2) or the old signal(2)) which just sets some global volatile sigatomic_t flag and test then clear that flag in convenient place in your code (e.g. in some event loop using poll(2)).

NB:请注意,fork与C编程无关( C99 ).这是 POSIX 和Linux之类的东西. Windows或 z/OS

NB: notice that fork is not about C programming (fork is not defined in the C11 standard n1570 or its predecessor C99). It is a POSIX and Linux thing. Windows or z/OS or an Arduino microcontroller don't have it natively, but are programmable in some standard C.

这篇关于使用switch语句分叉两个进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆