进程控制

网友投稿 593 2022-05-29

学习目标

了解进程相关概念

掌握fork/getpid/getppid函数的使用

熟练掌握ps/kill命令的使用

熟练掌握execl/execlp函数的使用

说出什么是孤儿进程,什么是僵尸进程

熟练掌握wait函数的使用

熟练掌握waitpid函数的使用

1、进程相关概念

程序和进程

程序:二进制文件,占用磁盘空间

进程:启动的程序

所有的数据都在内存中

需要占用更多的系统资源

CPU,物理内存

并行和并发

Concurrent = Two Queues One Coffee Machine

3、PCB

[tester@TesterPC ~]$ ulimit -a

4、进程的五种状态

2、进程控制

FORK(2) Linux Programmer's Manual FORK(2) NAME fork - create a child process SYNOPSIS #include #include pid_t fork(void);

data:初始化为非0全局变量 初始化为非0的static变量 bss:初始化为0全局变量 初始化为0的static变量 未初始化的变量 rodata:常量、只读变量

data:初始化为非0全局变量 初始化为非0的static变量 bss:初始化为0全局变量 初始化为0的static变量 未初始化的变量 rodata:常量、只读变量

回答问题:

fork函数的返回值

>0 ,父进程的返回值

=0 ,子进程的返回值

子进程创建成功之后代码的执行位置

父进程执行到哪,子进程就从哪开始执行

父子进程的执行顺序?

不一定,谁抢到CPU谁就执行

如何区分父子进程?

通过fork函数的返回值

Getpid/ getppid

Getpid - 得到当前经常的PID

Getppid - 得到当前进程的父进程的PID

我发现平台不同,执行的结果也不同?待理解是什么问题造成的???

Linux 平台: [master2@master2-server ProcessPro]$ gcc fork_demo001.c [master2@master2-server ProcessPro]$ ll total 48 -rwxrwxr-x 1 master2 master2 17592 Nov 26 15:03 a.out -rwxrwxr-x 1 master2 master2 17640 Nov 25 14:28 fork -rw-rw-r-- 1 master2 master2 1068 Nov 25 20:17 fork.c -rw-rw-r-- 1 master2 master2 584 Nov 26 15:00 fork_demo001.c [master2@master2-server ProcessPro]$ [master2@master2-server ProcessPro]$ [master2@master2-server ProcessPro]$ ./a.out Fork Befor i:0 Fork Befor i:1 Fork Befor i:2 Fork Befor i:3 这是父进程,进程ID:3362177 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 [master2@master2-server ProcessPro]$ 这是子进程,子进程ID:3362178,父进程ID:1 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 [master2@master2-server ProcessPro]$

使用VS Code执行: [Running] cd "/home/master2/ProjectData/ProcessPro/" && gcc fork_demo001.c -o fork_demo001 && "/home/master2/ProjectData/ProcessPro/"fork_demo001 Fork Befor i:0 Fork Befor i:1 Fork Befor i:2 Fork Befor i:3 这是父进程,进程ID:3368039 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 Fork Befor i:0 Fork Befor i:1 Fork Befor i:2 Fork Befor i:3 这是子进程,子进程ID:3368045,父进程ID:1 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 [Done] exited with code=0 in 0.075 seconds

循环创建多个子进程

#include #include #include int main(int argc, const char *agrs[]) { pid_t pid; int num = 4; int count = 3; int i; for (i = 0; i < num; i++) { printf("Fork Befor i:%d\n", i); } for (i = 0; i < count; i++) { pid = fork(); if (pid == 0) { break; } } switch (i) { case 0: printf("这是第1个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); break; case 1: printf("这是第2个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); break; case 2: printf("这是第3个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); break; default: break; } if (i == count) { printf("这是父进程,进程ID:%d \n", getpid()); } for (size_t i = 0; i < num; i++) { printf("Fork After i:%d\n", i); } return 0; }

执行结果

[master2@master2-server ProcessPro]$ ./a.out Fork Befor i:0 Fork Befor i:1 Fork Befor i:2 Fork Befor i:3 这是父进程,进程ID:3513910 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 [master2@master2-server ProcessPro]$ 这是第1个进程,子进程ID:3513911 父进程ID:1 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 这是第2个进程,子进程ID:3513912 父进程ID:1 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 这是第3个进程,子进程ID:3513913 父进程ID:1 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 [master2@master2-server ProcessPro]$

解决父进程先执行结束后显示错乱的问题。将父进程执行的时间大于子进程

#include #include #include int main(int argc, const char *agrs[]) { pid_t pid; int num = 4; int count = 3; int i; for (i = 0; i < num; i++) { printf("Fork Befor i:%d\n", i); } for (i = 0; i < count; i++) { pid = fork(); if (pid == 0) { break; } } switch (i) { case 0: printf("这是第1个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); break; case 1: printf("这是第2个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); break; case 2: printf("这是第3个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); break; default: break; } if (i == count) { printf("这是父进程,进程ID:%d \n", getpid()); sleep(1); } for (size_t i = 0; i < num; i++) { printf("Fork After i:%d\n", i); } return 0; }

[master2@master2-server ProcessPro]$ ./a.out Fork Befor i:0 Fork Befor i:1 Fork Befor i:2 Fork Befor i:3 这是父进程,进程ID:3518501 这是第1个进程,子进程ID:3518502 父进程ID:3518501 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 这是第2个进程,子进程ID:3518503 父进程ID:3518501 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 这是第3个进程,子进程ID:3518504 父进程ID:3518501 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 Fork After i:0 Fork After i:1 Fork After i:2 Fork After i:3 [master2@master2-server ProcessPro]$

进程相关的命令

Ps

Ps -aux | grep "xxx"

Ps -ajx | grep "xxx"

Kill - 向指定的进程发送信号

进程共享

刚fork出来之后:

两个地址空间用户区数据完全相同

后续各自进行了不同的操作:

各个进程的地址空间中的数据是完全独立的。

读时共享(节省内存空间)

写时复制

父子之间能否通过使用全局变量通信?

答案:不能

因为两个进程间内存不能共享

data:初始化为非0全局变量

初始化为非0的static变量

bss:初始化为0全局变量

初始化为0的static变量

未初始化的变量

rodata:常量、只读变量

data:初始化为非0全局变量

初始化为非0的static变量

bss:初始化为0全局变量

初始化为0的static变量

未初始化的变量

进程控制

rodata:常量、只读变量

读时共享,写时复制,用实例验证

#include #include #include int main(int argc, const char *agrs[]) { pid_t pid; int num = 4; int count = 3; int i; int counter = 200; /* for (i = 0; i < num; i++) { printf("Fork Befor i:%d\n", i); } */ for (i = 0; i < count; i++) { pid = fork(); if (pid == 0) { break; } } switch (i) { case 0: printf("这是第1个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); counter+=200; printf("---counter = %d\n", counter); break; case 1: printf("这是第2个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); counter+=200; printf("---counter = %d\n", counter); break; case 2: printf("这是第3个进程,子进程ID:%d 父进程ID:%d\n", getpid(), getppid()); counter+=200; printf("---counter = %d\n", counter); break; default: break; } if (i == count) { printf("这是父进程,进程ID:%d \n", getpid()); counter+=800; printf("---counter = %d\n", counter); sleep(1); } /* for (size_t i = 0; i < num; i++) { printf("Fork After i:%d\n", i); } */ return 0; }

[master2@master2-server ProcessPro]$ ./a.out 这是父进程,进程ID:3533218 ---counter = 1000 这是第1个进程,子进程ID:3533219 父进程ID:3533218 ---counter = 400 这是第2个进程,子进程ID:3533220 父进程ID:3533218 ---counter = 400 这是第3个进程,子进程ID:3533221 父进程ID:3533218 ---counter = 400 [master2@master2-server ProcessPro]$

任务调度

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:JAVA流程控制语句
下一篇:如何利用DG环境的备库来异机还原一个新主库
相关文章