为什么子进程的行为如此奇怪?
Why child process behaviour is so strange?
我写了一段创建子进程的代码。
代码片段:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
void B();
void C();
void D();
void E();
int main (){
int status;
printf("Name: %s, PID: %d, PPID: %d.\n", "A", getpid(), getppid());
if (fork() == 0) {
B();
}
if (fork() == 0) {
C();
}
wait(&status);
}
void B(){
//B process
int status;
printf("Name: %s, PID: %d, PPID: %d.\n", "B", getpid(), getppid());
if (fork() == 0) {
E();
}
if (fork() == 0) {
D();
}
wait(&status);
}
void C(){
//C process
printf("Name: %s, PID: %d, PPID: %d.\n", "C", getpid(), getppid());
}
void E(){
//E process
printf("Name: %s, PID: %d, PPID: %d.\n", "E", getpid(), getppid());
}
void D(){
//D process
printf("Name: %s, PID: %d, PPID: %d.\n", "D", getpid(), getppid());
}
问题是我得到了完全出乎我意料的输出。
日志:
Name: C, PID: 4571, PPID: 4570.
Name: D, PID: 4572, PPID: 4569.
Name: C, PID: 4573, PPID: 4572.
Name: C, PID: 4574, PPID: 4567.
Name: C, PID: 4575, PPID: 4569.
------------------------------
Name: A, PID: 4576, PPID: 4147.
Name: B, PID: 4577, PPID: 4576.
Name: C, PID: 4578, PPID: 4576.
Name: D, PID: 4580, PPID: 4577.
Name: E, PID: 4579, PPID: 4577.
------------------------------
Name: D, PID: 4582, PPID: 4579.
Name: C, PID: 4581, PPID: 4580.
Name: C, PID: 4583, PPID: 4582.
Name: C, PID: 4584, PPID: 4577.
Name: C, PID: 4585, PPID: 4579.
每次发射都由------------------------
为什么C进程运行多次,每次都改变他的PPID?
为什么我看不到来自 A 进程(父进程)的消息?
等待您的回答和 link 资源!
您看到了缓冲 stdout
这一事实的副作用。我将您的程序修改为:
- 每次调用
printf
后刷新 stdout
。
- 添加了根据缩进级别打印缩进的功能。主进程的缩进级别是
0
。主进程子进程级别缩进为1
,以此类推
我得到以下输出:
Name: A, PID: 694812, PPID: 23788.
Name: B, PID: 695816, PPID: 694812.
Name: C, PID: 693016, PPID: 694812.
Name: E, PID: 691184, PPID: 695816.
Name: D, PID: 695896, PPID: 695816.
Name: D, PID: 691792, PPID: 691184.
Name: C, PID: 696268, PPID: 691792.
Name: C, PID: 695220, PPID: 695896.
Name: C, PID: 694204, PPID: 695816.
Name: C, PID: 695496, PPID: 691184.
修改后的程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
void B();
void C();
void D();
void E();
void printIndent();
int indentLevel = 0;
int main (){
int status;
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "A", getpid(), getppid());
fflush(stdout);
if (fork() == 0) {
++indentLevel;
B();
}
if (fork() == 0) {
++indentLevel;
C();
}
wait(&status);
}
void B(){
//B process
int status;
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "B", getpid(), getppid());
fflush(stdout);
if (fork() == 0) {
++indentLevel;
E();
}
if (fork() == 0) {
++indentLevel;
D();
}
wait(&status);
}
void C(){
//C process
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "C", getpid(), getppid());
fflush(stdout);
}
void E(){
//E process
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "E", getpid(), getppid());
fflush(stdout);
}
void D(){
//D process
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "D", getpid(), getppid());
fflush(stdout);
}
void printIndent()
{
int i = 0;
for ( ; i < indentLevel; ++i )
{
printf(" ");
}
}
我写了一段创建子进程的代码。
代码片段:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
void B();
void C();
void D();
void E();
int main (){
int status;
printf("Name: %s, PID: %d, PPID: %d.\n", "A", getpid(), getppid());
if (fork() == 0) {
B();
}
if (fork() == 0) {
C();
}
wait(&status);
}
void B(){
//B process
int status;
printf("Name: %s, PID: %d, PPID: %d.\n", "B", getpid(), getppid());
if (fork() == 0) {
E();
}
if (fork() == 0) {
D();
}
wait(&status);
}
void C(){
//C process
printf("Name: %s, PID: %d, PPID: %d.\n", "C", getpid(), getppid());
}
void E(){
//E process
printf("Name: %s, PID: %d, PPID: %d.\n", "E", getpid(), getppid());
}
void D(){
//D process
printf("Name: %s, PID: %d, PPID: %d.\n", "D", getpid(), getppid());
}
问题是我得到了完全出乎我意料的输出。 日志:
Name: C, PID: 4571, PPID: 4570.
Name: D, PID: 4572, PPID: 4569.
Name: C, PID: 4573, PPID: 4572.
Name: C, PID: 4574, PPID: 4567.
Name: C, PID: 4575, PPID: 4569.
------------------------------
Name: A, PID: 4576, PPID: 4147.
Name: B, PID: 4577, PPID: 4576.
Name: C, PID: 4578, PPID: 4576.
Name: D, PID: 4580, PPID: 4577.
Name: E, PID: 4579, PPID: 4577.
------------------------------
Name: D, PID: 4582, PPID: 4579.
Name: C, PID: 4581, PPID: 4580.
Name: C, PID: 4583, PPID: 4582.
Name: C, PID: 4584, PPID: 4577.
Name: C, PID: 4585, PPID: 4579.
每次发射都由------------------------
为什么C进程运行多次,每次都改变他的PPID? 为什么我看不到来自 A 进程(父进程)的消息? 等待您的回答和 link 资源!
您看到了缓冲 stdout
这一事实的副作用。我将您的程序修改为:
- 每次调用
printf
后刷新stdout
。 - 添加了根据缩进级别打印缩进的功能。主进程的缩进级别是
0
。主进程子进程级别缩进为1
,以此类推
我得到以下输出:
Name: A, PID: 694812, PPID: 23788.
Name: B, PID: 695816, PPID: 694812.
Name: C, PID: 693016, PPID: 694812.
Name: E, PID: 691184, PPID: 695816.
Name: D, PID: 695896, PPID: 695816.
Name: D, PID: 691792, PPID: 691184.
Name: C, PID: 696268, PPID: 691792.
Name: C, PID: 695220, PPID: 695896.
Name: C, PID: 694204, PPID: 695816.
Name: C, PID: 695496, PPID: 691184.
修改后的程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
void B();
void C();
void D();
void E();
void printIndent();
int indentLevel = 0;
int main (){
int status;
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "A", getpid(), getppid());
fflush(stdout);
if (fork() == 0) {
++indentLevel;
B();
}
if (fork() == 0) {
++indentLevel;
C();
}
wait(&status);
}
void B(){
//B process
int status;
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "B", getpid(), getppid());
fflush(stdout);
if (fork() == 0) {
++indentLevel;
E();
}
if (fork() == 0) {
++indentLevel;
D();
}
wait(&status);
}
void C(){
//C process
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "C", getpid(), getppid());
fflush(stdout);
}
void E(){
//E process
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "E", getpid(), getppid());
fflush(stdout);
}
void D(){
//D process
printIndent();
printf("Name: %s, PID: %d, PPID: %d.\n", "D", getpid(), getppid());
fflush(stdout);
}
void printIndent()
{
int i = 0;
for ( ; i < indentLevel; ++i )
{
printf(" ");
}
}