课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体
由上图可以看出在OS中进程可以同时存在并且非常多
进程=内核task_struct结构体+程序的代码和数据
理解一个概念:如何理解进程动态运行?
只要我们的进程task_struct在不同的队列中就可以访问不同的资源
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合.
PCB也叫进程控制块,这个数据结构是在操作系统内部进行管理进程的,一般叫他内核数据结构
我们都知道开机是在加载OS,刚开始OS也是在磁盘中是一堆二进制文件,等待的时间是将磁盘中的文件拷贝到内存中,以便计算机可以开始执行操作系统的代码并进行初始化
在操作系统启动的时候,通常会创建一个特殊的进程,这个进程通常被称为 init 进程。init 进程是在操作系统引导过程中由内核启动的,它是用户空间中的第一个进程,负责系统的初始化和进程管理。
操作系统在启动时会创建 init 进程的进程控制块(PCB),用于描述和管理这个特殊进程的信息。进程控制块(PCB)是操作系统用来管理进程的数据结构,它包含了进程的状态、程序计数器、堆栈指针、内存分配情况、打开文件的状态等信息。
加强认识:OS对于进程管理是通过PCB进行管理的而不是将你的可执行程序加载到内存中对你的可执行程序管理
为什么要有PCB?因为OS要对进程管理
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
进程的task_struct本身内部的属性有哪些?
1. 启动
./xxx 本质就是让系统创建进程并运行----我们自己写的代码形成的可执行==系统命令==可执行文件。在linux中运行的大部分操作其实本质就是运行进程。
在windows中双击就是运行进程,在linux中./就是运行进程
2. 每一个进程都要有自己的唯一标识符,叫做进程pid3. ctrl+c在用户层面上就是终止进程,kill -9 pid 可以直接杀死进程
为什么要创建子进程?
我们想让子进程执行和父进程不一样的代码(由于机器的限制部分功能无法展示)
fork之后父子代码都是共享的,只不过进行判断了所以父与子运行不同
当调用fork()
时,操作系统会复制当前的进程,包括它的地址空间、文件描述符等,然后在新的进程中继续执行代码。在调用fork()
后,会出现两个几乎完全相同的进程:父进程和子进程。这两个进程的唯一区别在于fork()
的返回值不同:
- 在父进程中,
fork()
返回子进程的进程 ID。- 在子进程中,
fork()
返回 0。
fork()会有两个返回值,返回两次
fork()也是函数只不过是由os提供的,可以这样理解:在fork内部我们已经把子进程创建可以被调度了所以return两次
进程一定要具有独立性,即使我俩是父子也不影响,所以父子进程有自己独立的task_struct(也有自己独立的pid),而代码是只读的,数据原则是要分开的
ls /proc当你执行
ls /proc
命令时,会列出一系列以数字命名的目录,每个目录代表一个正在运行的进程或者系统相关的信息
ls /proc/x -d查看具体ls -l /proc/x 查看正在运行的进程可以看出有exe和cwd
exe
是一个指向正在执行的进程可执行文件的符号链接。通过查看这个符号链接,你可以知道该进程当前正在执行的可执行文件的路径
cwd
是一个指向进程当前工作目录的符号链接。通过这个符号链接,你可以了解到该进程当前的工作目录路径。
由于机器有限部分内容无法展示