一、进程的销毁

  • 1.释放资源

  • 2.记账信息

  • 3.将进程状态设置设置成僵尸状态

  • 4.转存储调度

二、进程终止的方法

1、正常退出

  • 1. void _exit ( int status)

    • status定义了进程终止状态,父进程通过wait来获取该值

    • 退出码为0正常退出,非0异常退出(8-16位为退出码,退出码在0-255之间)

    • echo $?   //上一条指令的退出码

  • 2. void exit ( int status ) 

    • exit( ) 最终也会调用_exit( )函数,调用前会刷新stdio流缓冲区

  • 3.return退出

    • 执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返回值作为exit的参数

【Linux】进程的控制

exit和_exit的区别

  • exit是函数

  • _exit是系统的API接口

注册退出处理程序

  • int atexit(void(*func)(void));

    • #include<stdlib.h>

    • 函数atexit()将func加到一个函数列表中,进程终止时会调用该函数列表的所有函数。

  • void  func(void);

    • atexit()在调用出错的时候返回非0值(不一定是-1);

    • 可以注册多个退出处理程序,当程序调用exit()时,这些函数的执行顺序和注册表顺序相反。

2、异常退出

  • 1. ctrl + c

  • 2. assert ( )

  • 3. abort ( )

  • 4. 信号终止

  • 5. 发生了软件事件,例如:定时器到期,进程执行的CPU事件超出限制,或者该进程的某个子进程退出。

  • 6. 硬件发生异常

三、进程等待

  • 子进程退出父进程不去回收,则可能造成僵尸进程的问题,无法杀掉,且会造成内存泄漏

  • 通过父进程可wait()函数等待并回收子进程资源、获取子进程退出信息

回收僵尸子进程

       系统调用wait( )等待调用进程的任一子进程死亡后,同时在参数status指向的缓冲区中返回该子进程的终止状态。

wait()

  • pid_t wait ( int * status ) 

    • 作用:   等待子进程结束,回收僵尸子进程

    • 头文件:#include<sys/types.h>

                                #include<sys/wait.h>

  • 返回值:成功返回被回收的子进程ID,失败返回-1

系统调用wait()执行如下动作:

  • 如果调用进程并无之前未被等待的子进程终止,调用将一直阻塞,直至某个子进程终止。如果调用时已有子进程终止,wait()即刻返回,并且释放资源、获取子进程退出信息。

  • 如果status非空,那么关于子进程如何终止的信息则会通过status指向的整型变量返回

  • 内核将会为父进程下所有子进程的运行总量追加进程CPU时间以及资源使用数据。

  • 将终止子进程的PID作为wait()的结果返回。

【Linux】进程的控制

【Linux】进程的控制

waitpid()

  • pid_t waitpid(pid_t pid , int * status ,int options);

    • 参数:

      • pid:pid=-1等待任一子进程,与wait等效

                              pid>0,等待当前进程ID为pid的子进程

                              pid=0等待本组进程任一一个子进程死亡

  •                status:WIFEXITED(status) :如果正常退出,返回真

                                    WEXITSTATUS(status) :返回子进程的退出码

  •                options:是一个位掩码,可包含0个或多个标志,一般写0(阻塞)

                                      WNOHANG进程没有结束返回0,不予等待,正常结束则返回子进程ID(非阻塞)

 【Linux】进程的控制

【Linux】进程的控制

正常退出执行结果:

【Linux】进程的控制

10秒以内在另一个终端下执行以下命令杀死子进程3132

【Linux】进程的控制

此时子进程非正常死亡,因此不执行 if(WIFEXITED)下的语句

【Linux】进程的控制

四、进程替换

   用fork创建子进程后执行的是和父进程相同的程序,子进程往往调用exec函数以执行另一个程序,当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动历程开始执行,调用exec函数并不创建新进程,调用exec前后改进程的id并未改变。

exec

v:vector 参数采用数组

l:list       参数采用列表

p:path   表示自动搜索环境变量PATH

e:envir   表示自己维护环境变量

 

execl(const char* path,const char* arg,...);

execlp(const char* file,const char* arg);

execle(const char* path,const char* arg,... , char* const envp[ ]);

execv(const char* path,char* const argv[ ]);

execvp(const char* file,char* const argv[ ]);

execve(const char* path,char* const argv[],... , char* const envp[ ]);

  • 如果调用成功则加载新的程序从启动代码开始执行,不再返回

  • 调用失败则返回-1

  • exec函数只有失败的返回值没有成功的返回值

【Linux】进程的控制

【Linux】进程的控制

 

 

 

 

 

 

 

 

 

 

 

 

相关文章: