什么是进程?程序又是什么?程序运行在操作系统来看是怎么做的?

        相信很多人都看到过课本上写的进程的概念,那么真的理解了吗?

        课本上是这样讲的,课本概念:程序的一个执行实例,正在执行的程序等。

        那么进程到底是什么?我先把内核层面上的概念拿出来:内核观点:承担分配系统资源(CPU时间,内存)的实体。

        相信很多人跟我一样,在学 linux 之前,每次写代码的时候,写好了一个程序,我们都讲把程序跑起来....,这个程序怎么怎么.....,但是现在这里概念要变一下了。

        当我们写好一个程序,将代码运行之后,那么写的程序在底层是来看是怎么运行的?怎么执行代码等等....,那么我这里讲详细讲讲。

        这里我先把进程的概念抛出来,进程是什么呢?

        进程 = 内核数据结构 + 代码和数据

        那么代码和数据倒是可以稍微理解,但是什么是内核数据结构?(以下我先暂且讲程序,先不讲进程)

        这里先问一下?在系统看来,每次运行完一个程序(运行完指的是从最开始运行到退出,就好比你写了一串代码,从 main 运行到 return 退出)才运行下一个还是可以运行很多个?

        这个问题我觉得很好理解,当你写一个死循环不退出,那么在起一个程序运行,那么这个是不是也可以运行?所以是不是就是说可以运行很多个?而不是只能一个一个运行!(我这里讲的一个一个运行依然是一个运行完毕退出才运行下一个)

        所以说,系统中是不是存在很多个被运行起来的程序,那么这么多程序被运行起来,需要操作系统管理吗?需要的对吧!怎么管理呢?六字真言:先描述,在组织

        这就跟我们每个人在学校一样,学校里有好几万学生,那么学校肯定也是需要管理我们这些学生,不然那就乱套了。

        那么既然都要被管理起来,怎么管理?我先继续用学生的例子讲:

        那么我们学生要被管理起来,是怎么管理的?是不是学校为每个学生创建了属于每个学生独有的(私有的)学生学号、班级、宿舍号等等,那么每个学生的这些信息,是不是都被在学生端的教务系统中有保存?我学校反正是这样,登录学生端的教务系统,里面保存每个学生的个人信息,有学生的学号、班级、宿舍号、身份证号等等,这些信息是可以直接标识到对应的每个学生个人的身上,而不是一个信息可以找到很多个学生!如果这样那么就乱套了。

        那么问题回归操作系统上来,系统中存在大量的程序,操作系统是不是也要管理,并且也是为每个进程创建属于它自己的信息?那么是什么呢?应该可以猜到一些吧?比如像学生学号一样表示程序的号码等等。

        但是学生的信息被保存在教务系统中,那么程序的信息被保存在哪里?

        在操作系统中,保存每个程序信息的叫 PCB 结构体,这个 PCB 是什么?在 linux 操作系统中 PCB 是 task_struct,那么我们可以看一看源代码:

上面就是一个程序运行起来,系统为它创建的 PCB结构体,那么这里面这么多属性,方法(c语言的结构体里面不能写方法,但是可以定义函数指针), 我们目前学的就用到里面的一点点。(mm_struct、files struct)这个结构就是进程的PCB结构!!!

每个学生有他的学号,班级等等,那么跟程序相关的,文件?内存?等等.....

所以这里就要变一下程序概念了!!!程序是指你写的可执行文件(代码和数据)!!!

进程 是指 内核数据结构 + 代码和数据

那么内核数据结构有什么?先谈谈 mm_struct 

当程序被加载起来,程序的代码和数据是要被加载到内存的,这里的内存指的是物理内存!!!

那么我们常用的不就是物理内存吗?不是的!我们常用的是虚拟内存!!!

这里又一个新的概念 虚拟地址空间,那么什么是虚拟地址空间?在PCB结构中是什么?每个进程都有吗? 

这个虚拟内存就是 mm_struct,是每个进程独有的,看过我之前讲的C/C++内存管理的就应该知道,内存有3G的用户空间和1G的内核空间如下图,那么虚拟内存呢,如下图:

当进程被创建出来,那么操作系统为了管理每个进程,为每个进程创建PCB结构体,这个PCB结构体中就包括它的虚拟地址空间 mm_struct,每个进程独有的!!!,而中间的是页表,是虚拟内存映射到物理内存上的中间介质,我这里暂且不讲页表。

所以,进程是什么?

进程 = 一堆内核结构 + 代码和数据

那么这里最后解释一下程序被运行起来,在操作系统看来是怎么样做的?

当程序在编译的时候,形成的可执行程序的时候,在还没被加载内存的时候,还在磁盘上的时候,也就是处于一个.exe文件(windows)的时候,程序内部是有地址的!!
因为操作系统不仅要遵守地址空间,编译器也要遵守,所以在编译器编译代码的时候,就已经形成了代码区、全局区等等,并且采用和linux一样的编址方式,每个变量、每行代码都进行了编址,所以程序在编译的时候,每个字段早已具有了虚拟地址。

当创建进程的时候,将可执行文件加载到物理内存中,可执行文件中的代码指令依然时按照虚拟地址编码的,并且加载到物理内存的时候,虚拟地址也一并加载到了物理内存,内部时虚拟地址,但是外部是物理地址然后因为可执行文件内部是按照linux编址的方式,所以每行代码指令可以对应到虚拟地址上的各个区域,页表的左边填的就是虚拟地址,右边是物理地址,通过页表映射到物理地址
当CPu通过虚拟地址获取到物理地址中的代码指令的时候,也获取到了地址,此时的地址依然是虚拟地址

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值