使用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)时,你应该总是处理以下三种情况 :
-
fork
给了0,你是在孩子的过程中 -
fork
给了一个正面的pid_t
,你在父进程中 -
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然后等待它们。