目录
预备知识
切入点
PCB
看见进程
pid
getpid 函数
预备知识
Linux -- 冯诺依曼体系结构(硬件)-CSDN博客https://blog.csdn.net/2301_76973016/article/details/143598784?spm=1001.2014.3001.5501
Linux -- 操作系统(软件)-CSDN博客https://blog.csdn.net/2301_76973016/article/details/143606208?spm=1001.2014.3001.5501
切入点
电脑是不是一次只能启动一个程序?不是的,电脑可以同时启动多个程序,我们打开微信的同时,也可以打开音乐软件听歌,不会因为打开了微信就不能听歌了。
每个程序都要加载到内存中才能执行,操作系统要不要管理被加载到内存的多个程序呢?显然是需要的。
那么操作系统如何管理加载到内存的程序呢?先描述再组织!
PCB
我们需要定义结构体 PCB(Process Control Block,即进程控制块),结构体中通常包含以下信息:
- 进程标识符:每个进程有一个唯一的标识符,以便操作系统可以区分不同的进程。
- 处理器状态信息:包括程序计数器、寄存器集合、条件码等,这些信息在进程切换时会被保存起来,以便进程重新获得CPU时间时恢复执行。
- 内存管理信息:比如进程地址空间的描述符,页表基址等,用于支持虚拟内存管理。
- 会计信息:例如进程开始时间、结束时间、使用的资源量等,用于性能监控和计费。
- 优先级信息:用于决定进程调度策略,高优先级的进程会优先得到CPU时间。
- 状态信息:进程的状态(如运行、就绪、等待等),这决定了进程在系统中的处理方式。
- I/O状态信息:包括打开文件列表、I/O缓冲区等,用于管理进程的输入输出操作。
- 其他信息:可能还包括安全信息、进程关系(父进程、子进程)等。
把程序加载到内存之后,操作系统并不认识这些程序,为了更好的管理这些程序,每一个进程都有自己的 PCB,PCB 中记录了进程的信息和属性,这样操作系统才可以管理这些进程,从此之后,对进程的管理,就变成了对 PCB 链表的增删查改。
PCB 链表组成了运行队列,运行队列中排队的是 PCB,每个 PCB 都会指向自己的可执行程序,CPU 在进程调度时,让进程去排队,本质上是让进程的 PCB 去排队,而不是可执行程序在排队,CPU在调度一个进程,只要找到PCB就可以,找到PCB就可以找到可执行程序,程序就可以执行了。
在Linux中,PCB 叫做 task_struct.
看见进程
pid
在计算机操作系统中,每个正在运行的进程都会被分配一个唯一的PID。当用户或应用程序需要与某个特定的进程交互时,可以通过PID来指定目标进程。例如,在 Linux 中,可以使用
kill
命令加上PID来终止某个进程;使用ps
命令查看当前系统中所有进程的信息,其中包括每个进程的PID。
getpid 函数
getpid
是一个系统调用,用于获取当前进程的进程标识符 PID,需要包含unistd.h
头文件 ,函数的返回值类型为 pid_t,它是一个整型类型,专门用于存储和处理进程ID,pid_t
通常在<sys/types.h>
头文件中定义,有时也会在<unistd.h>
中定义。
用以下代码来查看 pid:
#include<iostream>
using namespace std;
#include <unistd.h>int main()
{while(1){cout<<"process pid:"<<getpid()<<endl;sleep(1);}return 0;
}
testProcess:test.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f testProcess
运行代码:
可以看出当前进程的 pid 为 75735,每个进程的 pid 都是不一样的,当我们再次运行同一份代码时,会重新创建进程,此时进程的 pid 和上一次运行时的 pid 是不一样的:
当代码运行起来的同时,命令 while :;do ps ajx | head -1 && ps ajx | grep testProcess | grep -v grep;sleep 1;done 可以帮助我们看到进程的开始和结束: