在计算机的组成原理中,我们经常用计算机通常遵循冯诺伊曼体系结构,即控制器,存储器,运算器,和输入设备及输出设备,而通常将里面的存储器称为内存,运算器和控制器一起集成为CPU,输入输出统称为外设,我们日常写的代码由输入设备加载到内存中,由处理器识别成机器码,再通过CPU中的指令方式执行。这些指令是被以电路的方式集成在CPU中的,而代码则是通过指令集来完成的,存储器和外设的互动被称为io设备.
当一个程序被运行时,首先要加载到内存中,而CPU想要执行指令,只能去内存中以多种方式访问数据,控制器将数据定期的从内存刷新到外设中,例如,在C语言中,我们调用了scanf函数与printf函数,语言编辑器将我们的C语言一系列编译后成为指令可以识别的机器码,然后,操作系统分辨这行代码用到了IO,则通过系统调用,以及CPU的指令来达到将数据从内存写到外设中.
操作系统是一个对硬件与软件进行统一管理的软件,主要分为四大部分,分别为内存管理,文件管理,进程管理和驱动管理,一个完整的操作系统,通常只对外开放系统调用来完成一系列的操作,而系统调用对于用户来说是不友好的,因此有c++或shell来帮助用户执行这些硬件的IO操作,以及一些系统调用.
首先一个文件在磁盘里被称为一个文件,如果这个文件是一个可执行的二进制文件,当它被执行以后,就会被加载到内存里称作为进程,而在操作系统中,针对每一个被加载到内存中的进程,都会有一个单独的PCB进程块,这个PCB进程块是由操作系统来维护的,本质在linux代码中是一个命名为struct task_struct的一个结构体,其中包括进程的各种属性以及进程被分配的内存区域,静态文件是没有PCB的,所以一个完整的进程是需要有,二进制文件和管理这个二进制文件代码的一个PCB进程块.
因为操作系统中每一个不同的文件大小和属性是不一样的,所以需要有一个统一的标准来管理这些文件,因此分配给每一个文件一个PCB进程块,然后通过控制这些PCB进程块来间接控制这些文件,在linux中使用C语言的get PID可以得到一个进程的ID,这个ID就是PCB进程块结构体中的一个属性,唯一标识一个进程,而get PID是linux中的一个系统调用接口,每一个进程的PID在不同的时候启动是不一样的,因为一个文件在被加载到内存后,操作系统会给一个文件分配一个PCB进程块,而这个进程块不是固定的,所以他的PID也不固定.
之前提到了一个可执行文件,在被加载到内存以后,可以被称为进程,之后存在于磁盘的这个文件便没有用了,就算删掉以后可执行程序也不会被影响,比较特殊的是,linux中有一个目录为proc的目录,这是一个内存级别的目录,这里放着操作系统中正在运行的进程,通过以进程的PID命名的方式来分辨每一个进程所在的文件,这个目录下的文件可以查看当前正在运行的进程的属性.
如下图为linux下proc目录下的内容,每个数字为一表示一个进程,是进程的pid.
在linux中还有一个系统调用,就是c接口名字为get ppid,用于显示这个进程,父进程的ID,一般一个进程的父进程就是解释器,解释器通过创建子进程的方式来运行一个进程,我们使用C语言写的程序也可以通过调用fork系统调用来创建一个子进程,这个子进程有两个返回值,我们通常需要用一个条件判断来分给子进程和父进程不同的任务,如果这个进程是父进程,那么这个函数返回为子进程的PID,如果这个进程是子进程则返回零,当一个进程执行fork函数后,父进程和子进程同时共享fork函数后所有的代码.
如图打印进程的pid和ppid.可以看到hello.exe的ppid为bash解释器.证明解释器通过创建子进程的方式运行一个程序.
标签:文件,操作系统,一个,PCB,内存,linux,进程 From: https://www.cnblogs.com/qjwxlj/p/18212999