fork 和父子进程的理解

本文探讨了在Linux环境下使用C语言进行程序开发时,父子进程的执行顺序问题。通过具体代码示例展示了不同情况下进程执行的先后顺序,并解释了这种不确定性是由内核的调度策略决定的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚刚学Linux下C程序开发,看的是清华大学出版社出版的《Linxu C 程序基础与实例讲解》,我现在 对父子进程的执行顺序感到很困惑。书上的例子是先子进程后父进程。但在我的电脑上(Ubuntu 10.10)却是先父进程后子进程。
网上说,这是内核进程调度问题,请问一下这是怎么搞得,这样的程序是无法跨平台使用的吧?
附书上的例子:
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//fork()
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int  main()
{
     pid_t child_pid;
 
     child_pid=fork();
     switch (child_pid)
     {
         case  -1:
             printf ( "Create process failed!\n" );
             break ;
         case  0:
             printf ( "Child process with ID : %d .\n" ,( int )getpid());
             break ;
         default :
             printf ( "Parent process with ID : %d ,Child process ID : %d .\n" ,( int )getpid(),( int )child_pid);
             break ;
     }
     return  0;
}

运行结果:
Parent process with ID : 30394 ,Child process ID : 30395 .
Child process with ID : 30395 .
这段代码怎么又是先子进程了?
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// zombie.c
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int  main()
{
     pid_t pid;
     pid=fork();
     if (pid<0)
         printf ( "Error occurred!\n" );
     else  if (pid==0)
     {
         printf ( "ID=%d\n" ,( int )getpid());
         exit (NULL);
     }
     else
     {
         sleep(5);
         wait(NULL);
     }
     return  0;
调用了wait()函数的父进程马上阻塞自己,有wait()函数自动分析是否当前进程的某个子进程已经退出,如果找到这样一个一经变成僵进程的子进程,wait()函数就会收集这个子进程的信息,将它彻底终止并返回子进程结束状态值;如果没有找到这样一个子进程,wait()函数就会一直阻塞在这里,直到出现一个变成僵进程的子进程为止。
如果是下面这个程序,它的父进程先执行,父进程执行时就调用wait()函数,那父进程就阻塞了吧(停滞不前了),也就是说父进程在等子进程执行完毕,但子进程还没有执行。按理说这个程序应该不会结束的吧?但事实上不是这样的,这是为什么呢?
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// wait()
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int  main()
{
     pid_t child_pid,pid;
     int  status;
 
     child_pid=fork();
     switch (child_pid)
     {
         case  -1:
             printf ( "Create process failed!\n" );
             break ;
         case  0:
             printf ( "Child proces with ID %d!\n" <( int )getpid());
             break ;
         default :
             printf ( "Parent process with ID %d ,Child process ID %d !\n" ,( int )getpid(),( int )child_pid);
             pid=wait(&status);
             printf ( "Child process finished : PID=%d \n" ,child_pid);
             if (WIFEXITED(status))
                 printf ( "Child process exited with code %d \n" ,WEXITSTATUS(status));
             else
                 printf ( "Child process terminated abnormally!\n" );
             break ;
     }
     return  0;
}

运行结果:

Parent process with ID 31371 ,Child process ID 31372 !
Child process finished : PID=31372 
Child process exited with code 0 
fork就是这样的,父子进程的执行顺序不确定,谁先执行都有可能。
如果需要确定的执行顺序,就得想别的办法。
比如用vfork,保证子进程先运行。
父子进程哪个先运行时看内核的调度算法,在我们使用者看来,就是不确定的,LZ不要纠结了。switch 语句相当于并发处理,各个case之间一起运行的,父子进程之间谁运行时不可知的。1楼那个程序最后一个else里如果没有sleep和wait,谁先运行也是不可知的。 如果你很想控制他们谁先运行,可以使用sleep,先让一个睡一会嘛,只要sleep了,就肯定后运行。或者父进程中使用wait,等待子进程,那么很显然就是子进程在运行。  vfork的使用好像并不能控制运行顺序。 建议去看《unix坏境高级编程》,好好体会那里面的代码,会大有收获的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值