💯进程控制
00 min
2024-11-12
2024-11-21
type
status
summary
date
slug
tags
category
icon
password
📎
重新回顾一下上篇文章中的重要内容
1.掌握冯诺依曼系统
2.操作系统的概念和定位
3.深入理解进程概念,PCB是什么,操作系统是怎么管理进程的
  1. 学习进程状态,学会创建进程,掌握了什么是僵尸进程什么是孤儿进程还有他们的危害是什么
  1. 了解进程调度原则和优先级,理解进程的竞争性和独立性,理解什么是并发和什么是并行
  1. 理解环境变量,熟悉常见的环境变量和常见环境变量的指令
  1. 理解c语言空间分配规律什么是地址空间什么是页表其存在的意义是什么
💫
再说说本片文章要讲些什么:
1.创建子进程fork函数
2.等待进程的两个函数,是什么怎么用
3.进程替代的c语言函数接口,认识一下shell的运行原理

1.fork的常用用法

1.父进程希望复制自己然后分流父子进程执行不同的代码块例如:如父进程等待客户端请求,生成子进程来处理请求
2.一个进程要执行一个不同的程序
3.注意fork函数返回两次一次是父进程中返回子进程pid子进程中返回零
😆
main函数的返回值的意义:本质上表示的是进程完成时是否有出错,如果出错那有不同的数字代表出错原因,其中linux指令:echo $?表示的是上一个进程的退出码
exit和_exit之间的区别:
_exit是系统层面上的调用直接退出程序,不刷新缓冲区,exit是c语言层面上的调用会刷新缓冲区
 

2.wait函数

🥰
wait函数在操作系统和编程中扮演着重要的角色,主要用于控制进程或线程的执行顺序,实现同步和协作。以下是wait函数的主要作用:
  1. 等待子进程结束
      • 当一个进程(通常称为父进程)调用wait函数时,它会暂停自己的执行,直到它所等待的一个或多个子进程结束为止。
      • 这有助于确保父进程在继续执行之前,其子进程已经完成了它们的任务。
  1. 回收子进程资源
      • 当子进程结束时,它会向父进程发送一个信号,表明自己已经结束了。
      • 父进程通过调用wait函数来接收这个信号,并回收子进程占用的系统资源,如内存和文件描述符等。
      • 这有助于防止僵尸进程(已经结束但父进程尚未回收其资源的子进程)的产生。
  1. 获取子进程状态
      • wait函数还可以将子进程的终止状态传递给父进程。
      • 父进程可以通过检查这个状态来了解子进程是否正常终止、是否被信号中断等。
  1. 实现进程同步
      • 在多进程编程中,wait函数常用于实现进程之间的同步和协作。
      • 通过等待特定的子进程结束,父进程可以确保在继续执行之前,所有必要的子进程任务都已经完成。
  1. 支持多线程编程
      • 在一些多线程编程环境中(如Java中的Object类和Python中的threading.Condition类),wait函数也被用于线程之间的同步和协调。
      • 但需要注意的是,这种用法与操作系统层面的wait函数有所不同,通常是通过线程锁和条件变量来实现的。
 
 
如果子进程一直不退出,父进程在默认的wait的时候,调用这个系统调用的时候,也就是返回,称作阻塞状态也就是在等待子进程结束或者进入僵尸状态,也就是说进程进入阻塞状态不一定是在等待硬件资源也有可能是在等待子进程结束
 
 

3.waitpid方法

pid_t waitpid(pid_t pid,int *status,int options)
参数中pid为-1代表等待任意一个子进程,也可以传入一个子进程pid代表的等待该子进程
其中status参数是一个输出型参数用于获取信息,也就是我们可以自己创建一个status参数,然后传入函数后能返回一个包含status信息的参数
这里介绍两个status的宏WIFEXITED(status):若为正常终止子进程的返回的状态,则为真
(查看子进程是否正常退出)
WEXITSTATUS:若为非零,提取子进程退出码(查看退出码)
返回值是等待的子进程的pid的话就说明等待成功
waitpid的第三个参数option:其实就是再等待时候,一个等待方式的选择
:默认0就是阻塞状态将父进程放置在子进程PCB中的一个阻塞列表中,和硬件资源等待列表一样的道理
:WNOHANG:就是在等待过程中非阻塞,进行一个轮询
在while循环使用waitpid函数使用WNOHANG选项能使得父进程在运行的过程中等待子进程
 
 
🥰
以上内容介绍了进程等待,能不能做一下总结和讲一下进程等待的必要性呢?

4.进程替换

在上面内容的说明中,创建子进程都是fork创建然后再共用同一份代码,然后再一份代码中执行各自的任务,但是如果想要子进程和父进程执行完全不同的代码和任务那就需要用到进程替换
 
1.单进程版的程序替换“:其实就是使用函数execl将进程已经加载到物理内存中的数据和代码于execl中的路径对应的数据和代码进行一个替换然后从零开始运行这就是一个简单的单进程替换原理和过程
 
  1. exec*系列的函数替换成功之后,后续的代码就不执行了,除非替换失败
notion image
再exec家族中他们的后缀也都很好理解
l:代表list表示参数采用列表
v(vector):参数采用数组
p(path):有p自己搜索path环境变量
e(env):表示自己维护环境变量
其中execve才是系统调用其他的函数都会调用execve函数
 
这是一个微型shell
上一篇
The Annotated STL Source 观后感
下一篇
进程间通信