900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > linux基础——进程的退出及资源回收

linux基础——进程的退出及资源回收

时间:2024-06-18 13:36:56

相关推荐

linux基础——进程的退出及资源回收

文章目录

进程的退出returen 和 exit代码示例注册进程结束调用函数代码示例(on_exit):atexit代码示例(atexit) 进程资源的回收代码示例wait回收进程资源代码示例 waitpid代码示例 给指定进程发送信号(kill)僵尸进程代码示例 在进程的虚拟地址空间加载新的映像代码示例 使用system启动新的可执行程序代码示例

进程的退出

returen 和 exit

return只是函数的返回,而exit却是进程的结束。

void exit(int status);

#include <stdlib.h>void exit(int status);功能:终止进程参数:status:退出状态码。status&0377的值给父进程。返回值:永远不返回。

代码示例

test.c

#include <stdio.h>#include <stdlib.h>int main(void){getchar();exit(-1);}

执行结果

注册进程结束调用函数

在进程结束前,可以注册一些函数给进程,在进程结束时会自动调用这些被注册的函数。

on_exit(3)

#include <stdlib.h>int on_exit(void (*function)(int , void *), void *arg);功能:注册一个函数给进程,在进程终止的时候调用该函数参数:function:指定退出函数的名字void (*function)(int , void *)arg:指定退出函数的第二个参数返回值:0 成功非0 错误

代码示例(on_exit):

on_exit.c

#include <stdio.h>#include <stdlib.h>void doit(int n,void *arg){printf("n=%d\targ:%s\n",\n,(char *)arg);return;}int main(void){//向进程注册退出函数on_exit(doit,"beijing");getchar();exit(3);}

执行结果

atexit

atexit(3)

#include <stdlib.h>int atexit(void (*function)(void));功能:注册一个函数给进程,在进程终止的时候调用该函数参数:function:指定了要注册的函数的名字返回值:0 成功非0 错误

代码示例(atexit)

atexit.c

#include <stdio.h>#include <stdlib.h>//注册给进程的退出函数void doit(void){printf("hahha....\n");return;}int main(void){//向进程注册一个退出处理函数atexit(doit);getchar();return 0;}

执行结果

进程资源的回收

在进程退出后,父进程会回收子进程的资源。

使用wait(2)、waitpid(2)系统调用回收子进程的资源。

如果父进程早于子进程结束,那么父进程的子进程的父亲就改变成为init进程,这种进程被成为孤儿进程。

代码示例

lonely.c

#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main(void){pid_t pid;//创建子进程pid=fork();if(pid==-1){perror("fork");return 1;}if(pid==0){//子进程的代码sleep(5);printf("child...\n");//getchar();exit(0);}else{//父进程的代码printf("parent...\n");exit(0);}return 0;}

执行结果

wait回收进程资源

#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status);功能:等待进程改变状态。参数:status:退出状态码的地址。子进程的退出状态存放在这块地址空间里。可以使用一些宏检测退出原因。WIFEXITED(status) 如果正常死亡,返回真WEXITSTATUS(status) 返回子进程的退出状态和0377的与,那个值。WIFSIGNALED(status) 如果子进程被信号终止,返回真WTERMSIG(status) 检测被几号信号终止。只有上个宏为真的时候,才使用。返回值:-1 错误返回终止的子进程的pid

代码示例

wait.c

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>int main(void){pid_t pid;int s;//创建子进程pid=fork();if(pid==-1){perror("fork");return 1;}if(pid==0){printf("child pid=%d\n",\getpid());//sleep(5);getchar();exit(-1);}else{//等待子进程的结束wait(&s);if(WIFEXITED(s)){//子进程正常终止printf("status:%d\n",WEXITSTATUS(s));}//检测子进程是否被信号终止if(WIFSIGNALED(s)){//输出终止子进程的信号编号printf("signum :%d\n",\WTERMSIG(s));}printf("parent...\n");}return 0;}

执行结果

waitpid

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

功能:等待进程改变状态。参数:pid:< -1: pid取绝对值,如果子进程的组id等于这个绝对值,那么这个子进程就被等待。-1:等待任意子进程0:等待和当前进程有同一个组id的子进程> 0 等待子进程的pid是pid参数的子进程。status:同wait(2)参数的使用options:WNOHANG:非阻塞回收。0 阻塞回收返回值:-1 错误 0 没有子进程退出回收的子进程的pid

代码示例

waitpid.c

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>int main(void){pid_t pid;int s;//创建子进程pid=fork();if(pid==-1){perror("fork");return 1;}if(pid==0){printf("child pid=%d\n",\getpid());//sleep(5);getchar();exit(-1);}else{//非阻塞等待子进程的结束waitpid(-1,&s,WNOHANG);if(WIFEXITED(s)){//子进程正常终止printf("status:%d\n",WEXITSTATUS(s));}//检测子进程是否被信号终止if(WIFSIGNALED(s)){//输出终止子进程的信号编号printf("signum :%d\n",\WTERMSIG(s));}printf("parent...\n");}return 0;}

执行结果

给指定进程发送信号(kill)

kill -[信号编号] [进程的pid]

僵尸进程

子进程已经终止,但是父进程还没有回收子进程的资源,这时候的子进程处于僵尸状态,成为僵尸进程。

代码示例

zombile.c

#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <stdlib.h>int main(void){pid_t pid;pid=fork();if(pid==-1){perror("fork");return 1;}if(pid==0){exit(0);}else{sleep(20);wait(NULL);}return 0;}

在进程的虚拟地址空间加载新的映像

在子进程的虚拟地址空间加载新的影像,需要使用系统提供的一个家族的函数。

execl(3)

#include <unistd.h>extern char **environ;int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int execle(const char *path, const char *arg,\..., char * const envp[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execvpe(const char *file, char *const argv[],char *const envp[]);

execve(2)

#include <unistd.h>int execve(const char *filename, char *const argv[],\char *const envp[]);相同的execl list v vectorp PATH e 环境变量返回值:成功调用永远不返回-1 错误 errno被设置

代码示例

exec.c

#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>char *const ps_argv[]={"ps","-o","pid,ppid,pgrp,comm",NULL};int main(void){pid_t pid;//创建子进程pid=fork();if(pid ==-1){perror("fork");return 1;}if(pid==0){//加载新映像//execl("/bin/ps","ps","-o",\"pid,ppid,pgrp,comm",NULL);//execlp("ps","ps","-o",\"pid,ppid,pgrp,comm",NULL);execvp("ps",ps_argv);}else{wait(NULL);}return 0;}

执行结果:

使用system启动新的可执行程序

#include <stdlib.h>int system(const char *command);功能:执行一个shell命令参数:command:可执行命令返回值:-1 错误返回command的退出状态码。

代码示例

system.c

#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <stdlib.h>#include <unistd.h>int main(void){pid_t pid;pid=fork();if(pid==-1){return 1;}if(pid==0){execl("./myt","myt",NULL);//system("myt");exit(0);}else{wait(NULL);}return 0;}

执行结果

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。