使用switch语句分叉两个进程

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

#include  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; 

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

有一般规则。 当你使用fork(2)时,你应该总是处理以下三种情况

  1. fork给了0,你是在孩子的过程中
  2. fork给了一个正面的pid_t ,你在进程中
  3. fork 失败并给-1

人们(新手)有时会忘记最后(失败)的情况。 但它确实发生了,您可以通过在RLIMIT_NPROC进程中使用setrlimit(2)和RLIMIT_NPROC来降低对进程的限制来轻松测试这种情况,通常是祖父进程是你的shell(例如使用ulimit Bash内置 -u )。

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

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

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

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

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

为了避免僵尸进程 ,每个成功的fork应该稍后进行等待系统调用(例如waitpid(2)或wait或wait4(2)或wait3 )。 你在哪里等待,取决于你是否想让两个孩子同时跑步。 但是每个成功的fork应该有相应的成功wait调用。

如果您想要异步通知有关子进程更改的信息(特别是终止),请同时阅读有关SIGCHLD signal(7) (和signal-safety(7) )。 一种常见的方法是安装一个SIGCHLD信号处理程序(例如使用sigaction(2)或旧信号(2) ), volatile sigatomic_t设置一些全局volatile sigatomic_t标志并测试然后在代码中方便的位置清除该标志(例如在某些情况下)循环使用poll(2) )。

注意:请注意, fork不是关于C编程的( fork 没有在C11标准n1570或其前身C99中定义 )。 它是一个POSIX和Linux的东西。 Windows或z / OS或Arduino微控制器本身没有它,但可以在某些标准C中编程。

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

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

 #include  #include  #include  #include  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个孩子,你可以调用fork()2x。 所以用2个不同的变量调用fork然后等待它们。