快捷搜索:  汽车  科技

linux入门教程超详细交流学习,linux基础你掌握了几个

linux入门教程超详细交流学习,linux基础你掌握了几个#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

进程的退出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); }

  • 执行结果
  • linux入门教程超详细交流学习,linux基础你掌握了几个(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); }

  • 执行结果
  • linux入门教程超详细交流学习,linux基础你掌握了几个(2)

    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; }

  • 执行结果
  • linux入门教程超详细交流学习,linux基础你掌握了几个(3)

    进程资源的回收

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


    使用 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; }

    • 执行结果

    linux入门教程超详细交流学习,linux基础你掌握了几个(4)

    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; }

    • 执行结果

    linux入门教程超详细交流学习,linux基础你掌握了几个(5)

    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; }

    • 执行结果

    linux入门教程超详细交流学习,linux基础你掌握了几个(6)

    给指定进程发送信号(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[]); 相同的exec l list v vector p 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; }

  • 执行结果
  • linux入门教程超详细交流学习,linux基础你掌握了几个(7)

    使用 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; }

  • 执行结果
  • linux入门教程超详细交流学习,linux基础你掌握了几个(8)

    另外,作者在蓝桥云课上线了《Linux 操作系统原理剖析》,以 Linux 操作系统为基础对操作系统实现原理进行深入讲解,分析操作系统中的内存管理、进程管理、文件系统管理、设备管理、网络管理等几大子模块的实现原理。

    linux入门教程超详细交流学习,linux基础你掌握了几个(9)

    猜您喜欢: