linux下的C语言开发(进程等待)

所谓进程等待,其实很简单。前面我们说过可以用fork创建子进程,那么这里我们就可以使用wait函数让父进程等待子进程运行结束后才开始运行。注意,为了证明父进程确实是等待子进程运行结束后才继续运行的,我们使用了sleep函数。但是,在linux下面,sleep函数的参数是秒,而windows下面sleep的函数参数是毫秒。

下面对下面的程序进行解释:

1,fork():正如上一节讨论的,这个是父进程创建子进程,返回值小于0就表示失败;

                 创建成功的话,也会返回2两次,一次是子进程(返回值是0),一次是父进程的(返回值>0);

                  但是到底是谁先返回,并不一定,所以就存在问题了?

                 如果是父进程先返回,那么父进程的子进程的控制权就交给了init进程(下面在介绍),没问题,好;

                但是如果是子进程先返回,而父进程返回后又没有采取任何的子进程资源回收(回收什么?下面再说),那这个子进程就成为了僵尸进程,

                 他占用了进程号(系统里分配的进程号是有限的),如果父进程返回后,并没有结束,而是在此创建这样的字进程等过程,那么久而久之,

                系统就会出现崩溃的迹象;

2,回答上面的问题:

               问题1:init进程是什么?http://www.baike.com/wiki/init%E8%BF%9B%E7%A8%8B

                            linux在启动时,必须启动的第一个程序或者叫进程,此进程启动时,会读取/etc/inittab等配置文件里的参数,来启动运行级别,登入                            界面程序的启动等一系列工作,且监听有父进程结束后,子进程没有退出的情况,此时,init就会成为该子进程的父进程,从而实现

                           子进程资源的释放;

             问题2:子进程到底要释放什么资源?

                           在子进程返回或者使用exit()退出时,内核释放该进程所有的资源,包括打开的文件,占用的资源等,但是还保留了一些数据结构                             (包括进程号,运行时间,退出时状态),此时子进程成了僵尸进程,之所以有这些,是为了让父进程能通过调用函数而获取子进程的这些信息。所以为了避免僵尸进程,在子进程退出时,父进程要进行判断,具体用wait()或者waitpid()函数进行等待,此时主进                            程挂起,但是子进程生于的资源会得到释放,譬如说子进程id号;另外一种方法是,主进程里用signal函数SIGCHLD的处理函数,在处                         理函数里调用wait();还有方法:父进程signal(SIGCHLD,SIG_IGN),表示父进程不关心子进程的这些信息,子进程结束时,交由内核回                       收资源;另外的方法如,fork()两次,父进程fork()后,子进程在fork(),此时的孙进程就会由init接受;但是子进程还是要父进程处理;

          问题3: wait(int *status):   参数是指向子进程退出状态的一个代码;比如子进程exit(4). status就指向3;如果不关心,此参数可设为NULL;  

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4.   
  5. int main(int argc, char* argv[])  
  6. {  
  7.     pid_t pid;  
  8.   
  9.     pid = fork();  
  10.     if(0 == pid)  
  11.     {  
  12.         printf("This is child process, %d\n", getpid());  
  13.         sleep(5);  
  14.     }  
  15.     else  
  16.     {  
  17.         wait(NULL);  
  18.         printf("This is parent process, %d\n", getpid());  
  19.     }  
  20.   
  21.     return 1;  
  22. }  
    下面,我们需要做的就是两步,首先输入gcc fork.c -o fork, 然后输入./fork,就会在console下面获得这样的结果。

[cpp]  view plain copy
  1. [root@localhost fork]# ./fork  
  2. This is child process, 2135  
  3. This is parent process, 2134  
例子2:

下面通过例子来实战一下我们刚刚学到的内容:

 /* wait2.c */ 

 #include <sys/types.h> 

 #include <sys/wait.h> 

 #include <unistd.h> 

 int main() 

{ int status; 

pid_t pc, pr; 

pc = fork(); 

 if ( pc < 0) /* 如果出错*/ 

printf("error occured.\n"); 

 else if ( pc == 0 ) /* 子进程*/ 

printf("This is child process with pid of %d.\n", getpid()); 

 exit(3); /* 子进程返回3 */ 

else /* 父进程*/ 

 

 pr = wait(&status); 

 if ( WIFEXITED(status) ) /* 如果WIFEXITED返回非零值*/ 

 {   printf("The child process %d exit normally.\n", pr); 

 printf("the return code is %d.\n", WEXITSTATUS(status)); 

 

 else /* 如果WIFEXITED返回零 */ 

printf("The child process %d exit abnormally.\n", pr); 

 

编译并运行:   $ gcc wait2.c -o wait2 $ ./wait2  This is child process with pid of 1538. the child process 1538 exit normally. the return code is 3.  父进程准确捕捉到了子进程的返回值3,并把它打印了出来。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值