我在Linux中学习fork(),这是我的程序:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 int main(void){
5 int pid;
6 pid = fork();
7 if(pid < 0){
8 exit(1);
9 }
10 if(pid == 0){
11 fork();
12 fork();
13 printf("pid:%d ppid:%d\n",getpid(),getppid());
14 exit(0);
15 }
16 else{
17 printf("parent pid:%d ppid:%d\n",getpid(),getppid());
18 exit(0);
19 }
20
21 }
有时它工作正常,结果如下:
./test1.out
parent pid:27596 ppid:21425
pid:27599 ppid:27597
pid:27597 ppid:27596
pid:27598 ppid:27597
pid:27600 ppid:27598
但结果并不一致,更常见的是这样:
parent pid:27566 ppid:21425
pid:27567 ppid:27566
pid:27568 ppid:27567
pid:27569 ppid:1599
pid:27570 ppid:1599
这对我没用,所以我输入 $ ps aux 来找出1599的进程:(删除了一些列)
USER PID VSZ RSS STAT START COMMAND
linux 1599 63236 6316 Ss 09:03 /lib/systemd/systemd --user
有人能帮助我直截了当吗?
答案 0 :(得分:4)
我认为,有时会发生种族情况,父母会在孩子面前死亡。因此,孩子从初始过程成为孩子。在你的情况下,那必须是systemd。
无论如何,请注意,运行fork(); fork();
将产生4个进程,这可能(可能)不是您想要的。像对第一个一样使用控制结构来控制程序的行为。
答案 1 :(得分:4)
&#34;不一致&#34;您观察到的是因为有时父进程在子进程终止之前已退出。因此,这些子进程变为"orphans" 父流程对他们来说不是waiting。结果,他们重新成为了父母。到init进程。 传统上,&#34; init&#34;过程是1,它并不总是正确的。 POSIX将其保留为实现定义的:
所有现有子进程的父进程ID 调用进程的僵尸进程应设置为进程ID 实现定义的系统进程。也就是说,这些过程 应由特殊的系统过程继承。
因此,您会看到一个特定的PID作为父级(在您的示例中为1599),恰好是&#34; init&#34;在Linux上等效的进程。 systemd是Debian Linux发行版中使用的init变体 - 它遵循稍微复杂的实现。
在本质上,你观察到的是很正常的。理想情况下,您应收割所有流程,以避免zombie processes。
答案 2 :(得分:1)
这是因为父进程首先终止。
在Linux中没有ophan进程。它们被分配到init
进程。
如果要控制进程以使子进程首先终止,请使父进程等待。使用wait()
sys_call。
Example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int pid;
int pid2;
pid = fork();
if(pid < 0){
exit(1);
}
if(pid == 0){ // child process
pid2 = fork()
if (pid2 < 0)
exit(1);
if (pid2 == 0)
{
printf("pid:%dppid:%d\n",getpid(),getppid());
exit(0);
}
wait();
printf("pid:%d ppid:%d\n",getpid(),getppid());
exit(0);
}
else{ // parent process
wait();
printf("parent pid:%d ppid:%d\n",getpid(),getppid());
exit(0);
}
return 0;
}
systemd是Linux发行版中用于引导的init系统 用户空间并随后管理所有流程