我正在参加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;
但我不知道如何从目前为止的目标到达那里。我接近这个正确的方法了吗?我应该使用更好的方法吗?非常感谢。
答案 0 :(得分:3)
有一般规则。当您使用fork(2)时,您应该始终处理以下三个案例:
fork
给出0,您在孩子过程中fork
给出了肯定的pid_t
,您在父进程中fork
失败并给出-1 人们(新手)有时会忘记最后(失败)的情况。但它确实发生了,您可以通过在祖父进程中使用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)或wait
或wait4(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/OS或Arduino微控制器本身不具备该功能,但可在某些标准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,然后等待它们。