Linux:进程概念
文章目录
- 前言
- 一、冯诺依曼体系
- 二、操作系统(Operator System)
- 2.1.操作系统的概念
- 2.2 系统调⽤和库函数概念
- 三. 进程
- 3.1 基本概念
- 3.1.1 描述进程
- 3.1.2 task_struct
- 3.2 查看进程
- 3.2.1 getpid
- 3.2.2 proc
- 3.2.3 getppid
- 总结
前言
• 课本概念:程序的⼀个执⾏实例,正在执⾏的程序等
• 内核观点:担当分配系统资源(CPU时间,内存)的实体。
但这些观念都是建立在已经理解的基础上描述出来的,对于初学者一头雾水,所以本文将尽可能描述清晰其概念。
一、冯诺依曼体系
截⾄⽬前,我们所认识的计算机,都是由⼀个个的硬件组件组成
• 输⼊单元:包括键盘,⿏标,扫描仪,写板等
• 中央处理器(CPU):含有运算器和控制器等
• 输出单元:显⽰器,打印机等
注意!!!
• 这⾥的存储器指的是内存(但存储器不单单表示内存,详情参考下面图片)
• 不考虑缓存情况,这⾥的CPU能且只能对内存进⾏读写,不能访问外设(输⼊或输出设备)
• 外设(输⼊或输出设备)要输⼊或者输出数据,也只能写⼊内存或者从内存中读取。
• ⼀句话,所有设备都只能直接和内存打交道。
来举一个数据流动的例子:我们的设备中存在一个叫网卡的设备,它既是输入设备也是输出设备,当我们在QQ上发软件的时候,我们从键盘输入的信息传入输入设备网卡,写入内存,再传cpu经过某种特定的处理后返回内存,内存再由网卡作为输出设备,输入到另一个人的输入设备中,以类似过程处理,输出信息。本质上就是两台冯诺依曼体系结构的交互结果。
二、操作系统(Operator System)
操作系统是一款“搞管理”的软件!
操作系统面对任何“管理”场景都是:先描述,再组织!!!
操作系统在内存中的位置并不是固定的,它通常被加载到计算机的主存储器(RAM)中执行。当计算机启动时,操作系统会从硬盘或其他持久性存储设备中加载到RAM中,因为RAM的访问速度比硬盘快得多,这可以确保操作系统能够高效地运行。
2.1.操作系统的概念
任何计算机系统都包含⼀个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
• 内核(进程管理,内存管理,⽂件管理,驱动管理)
• 其他程序(例如函数库,shell程序等等)
设计OS的目的:
它管理系统资源、控制程序执行、改善人机界面、提供各种服务、合理组织计算机工作流程,并为用户有效使用计算机提供良好的运行环境。
总结:
计算机管理硬件
1. 描述起来,⽤struct结构体
2. 组织起来,⽤链表或其他⾼效的数据结构
2.2 系统调⽤和库函数概念
• 在开发⻆度,操作系统对外会表现为⼀个整体(防止被修改等原因),但是会暴露⾃⼰的部分接⼝,供上层开发使⽤,
这部分由操作系统提供的接⼝,叫做系统调⽤。
• 系统调⽤在使⽤上,功能⽐较基础,对⽤⼾的要求相对也⽐较⾼,所以,有⼼的开发者可以对部分系统调⽤进⾏适度封装,从⽽形成库,有了库,就很有利于更上层⽤⼾或者开发者进⾏⼆次开发。库函数和系统调用是上下层的关系
三. 进程
3.1 基本概念
• 课本概念:程序的⼀个执⾏实例,正在执⾏的程序等
• 内核观点:担当分配系统资源(CPU时间,内存)的实体。
但说人话进程=内核数据结构对象+自己的代码和数据
&& 进程=PCB(task_struct)+自己的代码和数据
3.1.1 描述进程
基本概念
• 进程信息被放在⼀个叫做进程控制块的数据结构中,可以理解为进程属性的集合
当一个程序需要被执行时,它就会类似进行类的实例化过程来构造结构对象,这个对象包含各种信息,这些信息是一个进程发生的条件等。
• 课本上称之为PCB(process_control_block),Linux操作系统下的PCB是:task_struct
因为OS必然要对多个加载到内存中的程序进行管理,因此进程的管理会以链表的增删改查来进行。因此这个管理过程是动态的!!!
3.1.2 task_struct
内容分类(结构体成员)
• 标⽰符:描述本进程的唯⼀标⽰符,⽤来区别其他进程。
• 状态:任务状态,退出代码,退出信号等。
• 优先级:相对于其他进程的优先级。
• 程序计数器:程序中即将被执⾏的下⼀条指令的地址。
• 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
• 上下⽂数据:进程执⾏时处理器的寄存器中的数据[休学例⼦,要加图CPU,寄存器]。
• I/O状态信息:包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使⽤的⽂件列表。
• 记账信息:可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等。
• 其他信息
组织进程
可以在内核源代码⾥找到它。所有运⾏在系统⾥的进程都以task_struct链表的形式存在内核⾥。
总结:我们自己写的程序,不会直接由硬件运行,它首先保存在磁盘中,然后当需要运行它的时候,它会被加载(也可以理解成拷贝)到内存中,然后操作系统中的进程管理(也是一个程序)会描述这个程序的各种属性(这些属性由task_struct的成员变量生成),然后组织描述过后的这个进程与其它正在运行的进程形成一个链表
3.2 查看进程
3.2.1 getpid
- 通过系统调用来获取进程
操作系统提供了一个getpid()函数可以获取,包含在头文件<sys/types.h>中
执行如下命令可以查看详细信息
man getpid
实验:我们建立一个myprocess.c 的文件并形成可执行文件
其代码为
//myprocess.c
#include<srdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
while(1)
{
sleep(1);
printf("我是一个进程,我的id:%d",getpid());
}
return 0;
}
执行结果如下可以验证它是一个正在执行的进程:
存在一个指令可以查看正在执行的所有进程
ps ajx
ps是指令 后面的ajx是格式可以随意增删达到不同显示效果
打开相同用户的第二个窗口,第一个窗口运行myprocess,输入以下命令行可以查看正在执行的myprocess进程信息
ps ajx | head -1 && ps ajx |grep myprocess
小知识点: 我们使用上面命令时最后再添加grep -v grep 就可以不显示带grep进程
同样的我们能够用指令结束一个进程,与ctrl+c结束命令相同原理
kill -9 PID
3.2.2 proc
在Linux的目录结构中有一个/proc目录,它是内存级的文件系统,它能让我们通过文件形式来动态查看正在执行的进程,当一个进程发生时,它就会出现在/proc中,结束或被kill时就会消失。
我们同样执行上面代码的同时,在/proc下面找到其进程包含的信息
我们首先需要了解task_struct两个成员变量exe和cwd
- exe:
exe 是一个符号链接,指向启动该进程的可执行文件。通过访问这个链接,你可以查看或调试与该进程关联的可执行文件。需要注意的是,如果可执行文件已经被删除或移动,这个链接可能会失效,指向一个不存在的文件。
当我们在一个窗口删除文件的时候可以发现文件在另一个窗口仍在运行!!这是因为我们正在运行的那个文件是从磁盘拷贝(加载)过去的只不过exe会显示deleted
- cwd(current work dir):
cwd 是一个符号链接,指向该进程的当前工作目录。通过访问这个链接,你可以快速定位到进程正在操作的文件系统位置。这对于理解进程的行为和调试文件系统问题非常有帮助
当我们运行程序的时候,执行fopen这个函数的时候新建一个“hello.txt”的文件,它会在当前目录下创建,所依据的就是cwd的路径
此时就可以根据此种方式来修改"hello.txt"的创建位置
系统调用chdir:可以修改文件的cwd
3.2.3 getppid
在Linux中所有的子进程都是由父进程创建的!
系统调用getppid:返回自己的父进程
同时我们可以反复执行这个程序,可以发现它自己的进程id一直在变,可是父进程却一直相同
接着查看这个父进程,它是bash!
bash:命令行解释器(本质是一个进程)
我们每登录一次云服务器的时候,操作系统会为每一个登录用户分配一个bash
下面图片就是一个命令行解释器,当我们不输入时,bash就会卡在这里,输入指令之后,它就会分析并执行这个bash,所以结合上面的cwd,我们用的每个命令“ls pwd …”(这些子进程的父进程都是bash)都是把这个命令结合其cwd,找到特定的路径文件并执行!!!!
总结
本文主要介绍了进程的一些基本概念,并展示了一些查看进程的方式,以及bash的概念