linux进程控制
2021/11/14 7:10:17
本文主要是介绍linux进程控制,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1. 创建一个子进程
-
程序demo
#include <sys/types.h> #include <unistd.h> pid_t fork(void); // 创建一个子进程 pid_t getpid(void); // 获取当前进程的id pid_t getppid(void); // 获取当前进程父进程的id
-
fork函数返回值:
失败 返回 -1
成功 两次返回
父进程返回子进程的 pid_t
子进程返回 0 -
创建一个子进程的程序:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { printf("Begin ..\n"); pid_t pid = fork(); if (pid < 0) { perror("fork err\n"); exit(1); } if (pid == 0) { printf("I am a Child, pid = %d, ppid = %d \n", getpid(), getppid()); } else if (pid > 0) { printf("I am a Parent, childpid = %d, selfpid = %d, ppid = %d \n", pid, getpid(), getppid()); sleep(1); // 如果不加sleep,父进程先消亡,此时子线程会变成孤儿线程 } printf("End ...\n"); return 0; }
-
输出结果
Begin .. I am a Parent, childpid = 73714, selfpid = 73713, ppid = 73479 I am a Child, pid = 73714, ppid = 73713 End ... End ...
-
为什么会执行两次printf(“End …\n”)函数呢?
在fork函数生成子进程之后,父进程和子进程都会执行fork语句之后的代码。 -
补充:linux查看进程信息的命令
查看进程信息:ps aux
查看进程组信息:ps ajx
给进程发送一个信号:kill
杀死一个进程:kill -9 pid
2. 创建多个子进程
-
创建多个子进程的程序:
int main() { printf("Begin ..\n"); for (int i = 0; i < 5; i++) { pid_t pid = fork(); if (pid < 0) { perror("fork err\n"); exit(1); } if (pid == 0) { printf("I am a Child, pid = %d, ppid = %d \n", getpid(), getppid()); break; // 子进程退出for循环 } else if (pid > 0) { printf("I am a Parent, childpid = %d, selfpid = %d, ppid = %d \n", pid, getpid(), getppid()); sleep(1); } } printf("End ...\n"); return 0; }
-
执行结果:
Begin .. I am a Parent, childpid = 74179, selfpid = 74178, ppid = 73479 I am a Child, pid = 74179, ppid = 74178 End ... I am a Parent, childpid = 74182, selfpid = 74178, ppid = 73479 I am a Child, pid = 74182, ppid = 74178 End ... I am a Parent, childpid = 74192, selfpid = 74178, ppid = 73479 I am a Child, pid = 74192, ppid = 74178 End ... I am a Parent, childpid = 74202, selfpid = 74178, ppid = 73479 I am a Child, pid = 74202, ppid = 74178 End ... I am a Parent, childpid = 74203, selfpid = 74178, ppid = 73479 I am a Child, pid = 74203, ppid = 74178 End ... End ...
如果子进程不及时退出for循环,子进程也会生成子进程,程序执行完不单单是生成5个子进程了。
3. 进程间共享
物理内存共享模式:读时共享,写时复制。
-
进程共享验证程序
int main() { printf("Begin ..\n"); int var = 100; pid_t pid = fork(); if (pid == 0) { printf("I am a Child, var = %d, pid = %d, ppid = %d \n", var, getpid(), getppid()); var = 0; // 子进程修改 var 变量的值 printf("I am a Child, var = %d, pid = %d, ppid = %d \n", var, getpid(), getppid()); } else if (pid > 0) { sleep(3); printf("I am a Parent, var = %d, childpid = %d, selfpid = %d, \ ppid = %d \n", var, pid, getpid(), getppid()); } printf("End ...\n"); return 0; }
-
输出结果:
Begin .. I am a Child, var = 100, pid = 74447, ppid = 74446 I am a Child, var = 0, pid = 74447, ppid = 74446 End ... I am a Parent, var = 100, childpid = 74447, selfpid = 74446, ppid = 73479 End ...
4. execl函数族
-
execl函数的作用:
fork创建子进程后执行和父进程相同的程序,子进程可以调用execl函数执行另一个程序。当一个进程调用execl函数时,该进程的用户空间代码和数据完成被新程序替换,从新程序的启动例程开始执行。
-
常用的execl函数
int execl(const char *path, const char *arg, .../* (char *) NULL */); int execlp(const char *file, const char *arg, .../* (char *) NULL */);
execl 执行其它程序
execlp 执行其它程序时,使用PATH变量,执行的程序可以不用加路径
file 要执行的程序
arg 参数列表,最后一个参数以NULL结尾
返回值,只有失败才返回 -
程序demo
int main() { //execl("/bin/ls", "ls", "-l", "--color=auto", NULL); execlp("ls", "ls", "-l", "--color=auto", NULL); perror("exec err"); return 0; }
注:第二个 “ls” 是一个无用的参数占位符
5. 孤儿进程与僵尸进程
孤儿进程:父进程死了,子进程被init进程领养
僵尸进程:子进程死了,父进程没有回收子进程的资源(PCB)
如何回收僵尸进程:杀死父进程
-
孤儿进程demo
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { printf("Begin ..\n"); pid_t pid = fork(); if (pid < 0) { perror("fork err\n"); exit(1); } if (pid == 0) { printf("I am a Child, pid = %d, ppid = %d \n", getpid(), getppid()); sleep(5); } else if (pid > 0) { printf("I am a Parent, childpid = %d, selfpid = %d, ppid = %d \n", pid, getpid(), getppid()); } printf("End ...\n"); return 0; }
-
输出结果
Begin .. I am a Parent, childpid = 74966, selfpid = 74965, ppid = 73479 End ... [zhpng@iZuf6ddpzz3ipktm5kj01cZ webserver]$ I am a Child, pid = 74966, ppid = 1 End ...
6. 子进程回收
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *wstatus); pid_t waitpid(pid_t pid, int *wstatus, int options);
wait函数回收子进程,查看子进程的死亡原因。
-
作用
阻塞等待
回收子进程资源
查看子进程死亡原因 -
pid_t wait(int *status)
status 出参,死亡原因
返回值
成功 返回终止的子进程ID
失败 返回 -1 -
子进程死亡原因
正常死亡:WIFEXITED,如果WIFEXITED为真,使用WEXITSTATUS得到退出状态
非正常死亡:WIFSIGNALED,如果WIFSIGNALED为真,使用WEXITSTATUS得到信号 -
wait函数回收多个子进程demo
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> int main() { printf("Begin ..\n"); int i = 0; pid_t pid; for (i = 0; i < 5; i++) { pid = fork(); if (pid == 0) { printf("I am child, pid = %d \n", getpid()); break; } } sleep(i); if (i == 5) { for (i = 0; i < 5; i++) { pid_t wpid = wait(NULL); printf("wpid = %d \n", wpid); sleep(1); } sleep(1); } printf("End ...\n"); return 0; }
-
输出结果
Begin .. I am child, pid = 76074 I am child, pid = 76075 I am child, pid = 76071 I am child, pid = 76072 I am child, pid = 76073 End ... End ... End ... End ... End ... wpid = 76071 wpid = 76072 wpid = 76073 wpid = 76074 wpid = 76075 End ...
这篇关于linux进程控制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法