进程控制
【摘要】 了解进程相关概念
掌握fork/getpid/getppid函数的使用
熟练掌握ps/kill命令的使用
熟练掌握execl/execlp函数的使用
说出什么是孤儿进程,什么是僵尸进程
熟练掌握wait函数的使用
熟练掌握waitpid函数的使用
学习目标
-
了解进程相关概念
-
掌握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 <sys/types.h>
#include <unistd.h>
pid_t fork(void);


data:初始化为非0全局变量
初始化为非0的static变量
bss:初始化为0全局变量
初始化为0的static变量
未初始化的变量
rodata:常量、只读变量
data:初始化为非0全局变量
初始化为非0的static变量
bss:初始化为0全局变量
初始化为0的static变量
未初始化的变量
rodata:常量、只读变量
![#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, const char *agrs[])
{
pid_t pid;
int num = 4;
for (size_t i = 0; i < num; i++)
{
printf("Fork Befor i:%d\n",i);
}
pid = fork();
if (pid > 0)
{
printf("这是父进程,进程ID:%d\n",getpid());
}
else if (pid == 0)
{
printf("这是子进程,子进程ID:%d,父进程ID:%d\n", getpid(), getppid());
}
for (size_t i = 0; i < num; i++)
{
printf("Fork After i:%d\n",i);
}
return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, const char *agrs[])
{
pid_t pid;
int num = 4;
for (size_t i = 0; i < num; i++)
{
printf("Fork Befor i:%d\n",i);
}
pid = fork();
if (pid > 0)
{
printf("这是父进程,进程ID:%d\n",getpid());
}
else if (pid == 0)
{
printf("这是子进程,子进程ID:%d,父进程ID:%d\n", getpid(), getppid());
}
for (size_t i = 0; i < num; i++)
{
printf("Fork After i:%d\n",i);
}
return 0;
}
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图
墨迹绘图](https://bbs-img.huaweicloud.com/blogs/img/20211212/1639319720284078056.png)
- 回答问题:
- 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 <stdio.h>
#include <unistd.h>
#include <sys/types.h>
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 <stdio.h>
#include <unistd.h>
#include <sys/types.h>
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 <stdio.h>
#include <unistd.h>
#include <sys/types.h>
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]$
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)