一段程序的穷途一生

#一段程序的穷途一生
##前言
本篇博客讲述一段程序的生命周期,起始点从二进制代码开始,至于如何生成的二进制码(编译汇编过程),由于篇幅限制,就姑且略过了,如果有机会会在另外的博客中书写。一段程序的一生包括三个抽象概念:进程,虚拟存储和文件系统。本文的介绍过程也是针对这三个抽象对程序的生命周期进行总结理解的。
##文件系统-童年
大家都知道,最初的程序都存储在非易失存储器中。在操作系统中,非易失存储被抽象为文件。这是第一个抽象。这个在Linux系统中尤其能够看出来。当我们把一个新添加的存储硬件添加到系统中的时候,当你需要使用它的时候需要首先对他进行挂载。挂载之后,我们就可以像对待文件那样操作设备了。
###文件系统的分区及引导
文件系统的物理实体就是一块或者多块磁盘,磁盘可以划分为一个或多个分区,每个分区中有独立的文件系统。磁盘的第0号扇被称为主引导分区(Master Boot Record, MBR),用来引导计算机。在MBR的结尾是分区表(相当于我们熟悉的C盘D盘),此处记录分区的大小以及起始地址等信息。分区表中的一个分区被标记为活动分区。活动分区就是我们说的系统盘(Window系统中通常用C盘作为系统盘,Linux系统中通常把活动分区放在/挂载在目录下)。活动分区在装系统的时候在引导块中写入引导信息。所以当计算机出现问题时,通常可以用WinPE进入系统修复MBR或者用easyBCD修复引导块内容,就可以重新使用系统了。
###文件系统的实现
文件系统的实现和管理主要依靠三个重要的概念:inode(i节点),目录,文件。
####文件
文件系统管理的最终目标就是实现文件的读写等操作,也是文件系统需要管理的核心。我们通常用的文件有两种格式,一种字符文件,通过ascii编码过的,对于人的阅读是友好的。另一种是二进制文件,因为后面要详细介绍二进制文件的结构,这里仅仅给出大致的一个文件结构就可以了。二进制文件是一种结构化的文件,通常用的可执行文件是ELF格式的。图1(a)个是可执行文件的结构图,图1(b)是动态链接库的结构图。(二进制文件是按照分段的方式进行存储的,为后来的段页式管理提供方便)
可执行文件动态链接库文件
###inode(i节点)
上面介绍的文件只是存储文件二进制,但是关于文件有很多的元数据信息。如果文件的大小,文件的类型,文件的权限等等问题是单独存储在一个叫做inode的数据结构中的。每一个文件都有inode数据结构,对系统级别的程序员程序员们来讲,文件的打开并不是真的把文件全部读入内存当中,而是把inode节点读入内存。inode节点中最重要的数据就是数据的存储位置信息,这个信息指示了文件内容的实际存储位置。inode节点中如何存储数据块信息就决定了文件大小的上限。Linux采用ext3作为文件系统,采用多级混合索引方案。结构图跟下图差不多。
多级混合索引
####目录
目录就是文件夹,在很多系统中目录就是一种文件,所以目录也会有对应的inode。目录的作用是组织文件系统,便于查找文件。目录采用树形结构存储,常说的目录树说的就是目录的存储结构了。采用树形结构由很多好处,比如可以分用户进行管理,在不同目录下的文件可以重名(相同目录下当然不能重名),树形结构也便于文件查找。为了便于存储和方便查找,目录树中只存储文件名和inode节点的对应关系,查找使用对应的文件时,能够按照文件结构快速的查找文件,从而找到对应的inode节点。
目录

总结一下的话,三者之间的关系是:
三者之间的关系
###文件系统杂谈
文件系统除了上述三个最主要内容以外,还有两个重要的概念:

  1. 空闲空间管理。文件系统将空闲空间组织成一个个的大一点的块结构,将块结构的最后位置组织成指向下一个块的链表结构,叫做空闲块链表法。
  2. 共享文件。共享文件就是将两个目录链接到同一个文件,这样的文件叫做符号链接。这样的符号链接能够节省大量的存储空间,但是处理文件时候的方法也会有所不同。
    ###程序的存储
    一般来说,与可执行文件相关的有两种文件,一种是可执行文件,一种是库文件(编译链接的时候使用)。它们按照一定的二进制格式文件进行存储,有些标记是为了帮助操作系统加载到内存中使用的,比如分段的时候指定起始地址。不论哪种文件,在磁盘中的存储都包含目录项,inode项和具体文件项。考虑我们在shell外壳中输入./run命令时,实际上仅仅把文件路径名传递给操作系统,系统通过目录查找到指定的inode节点,然后就可以找到指定的可执行文件。

如果将程序的运行比作人生,那么程序在文件系统中的程序就好比人生的童年。文件系统中的程序不需要去考虑竞争CPU资源。它出生的地方就像目录结构,山东省-泰安市-新泰市,可以通过这个树形目录结构寻找。而且不论后面有多大的作为,永远都是来自磁盘的一块地方。
##进程线程管理-青年
程序的运行需要代码,多道处理器结构中,不能像执行单道程序一样,需要记录程序运行的中间环境,这就用到了进程。进程是资源分配的基本单位,线程是处理器执行的基本单位。我们的程序在执行之前,先要将程序打包成一个进程。进程是程序的运行过程,进程记录程序运行需要的系统资源和运行环境。有了进程,我们才可以对处理器进行多道程序管理,才可以供多个用户同时使用。
###进(线)程状态
进(线)程具有动态性的特点,所以进(线)程就有不同的状态以充分利用操作系统的资源和并发性。进(线)程主要有三种状态:就绪,活动和阻塞状态。为了实现操作系统或者父进程能够控制进程的状态,便于调试程序,操作系统引入了挂起状态。各状态的转换结构如下图所示:
状态转换图
挂起是一种主动行为,因此恢复也应该要主动完成。挂起(suspend)不释放CPU,如果任务优先级高就永远轮不到其他任务运行,一般挂起用于程序调试中的条件中断,当出现某个条件的情况下挂起,然后进行单步调试。挂起状态用在程序调试过程中。
###进程PCB和线程TCB
进程是资源分配的单元,所以进程控制表示表主要记录进程的资源。主要记录的内容有:地址空间,全局变量,打开文件和子进程等。线程是处理器调度的基本单位,所以线程主要记录处理器执行需要的内容。主要记录的内容有:程序计数器,寄存器,堆栈和状态等。
###进(线)程调度
关于进线程调度有很多内容,比如调度需要互斥同步,防止死锁等,这里由于仅仅是讲简单的进线程调度方法,并不是针对各种问题进行说明,相关的问题会在后面的博客更新。在此,只说明进线程的调度只说明多级反馈队列调度算法。

  1. 应设置多个就绪队列,并为各个队列赋予不同的优先级。优先级从第一个到后面依次减小,优先级越高的队列时间片越少。
  2. 当第一个新进程进入内存后,首先将它放入第一个队列的末尾,按照FCFS的原则排队等待调度。
  3. 仅当第一队列空闲时,调度程序才调用第二队列中的程序运行,仅当第1~(i-1)队列为空时,才会调度第i个队列中进程运行。
    ###Linux系统中的进程线程实现
    Linux系统中多线程的实现通过轻型进程(LWP,Light Weight Process)实现。
    ####内核级线程
    内核级线程(KST,Kernel Support Threads),内核级线程是在内核的支持下运行的,在内核空间中实现。优点有:多处理器同时运行,线程切换速度快。缺点:线程切换需要从用户态切换到内核态运行,这个时间开销很大。
    ####用户级线程
    用户级线程(ULT,User Level Threads),用户级线程运行在用户空间。优点:线程切换速度快,调度算法自定义。缺点:系统调用阻塞问题,单纯的用户线程不能够利用多处理机的并行。
    ###轻量级进程
    轻量级进程(LWP,Light Weight Process),与普通进程相比,LWP与其他进程共享所有(或大部分)它的逻辑地址空间和系统资源;与线程相比,LWP有它自己的进程标识符,优先级,状态,以及栈和局部存储区,并和其他进程有着父子关系;这是和类Unix操作系统的系统调用vfork()生成的进程一样的。另外,线程既可由应用程序管理,又可由内核管理,而LWP只能由内核管理并像普通进程一样被调度。在大多数系统中,LWP与普通进程的区别也在于它只有一个最小的执行上下文和调度程序所需的统计信息,而这也是它之所以被称为轻量级的原因。一般来说,一个进程代表程序的一个实例,而LWP代表程序的执行线程(其实,在内核不支持线程的时候,LWP可以很方便地提供线程的实现)。
    LWP的一个重要作用是提供了一个用户级线程实现的中间系统。LWP可以通过系统调用获得内核提供的服务,因此,当一个用户级线程运行时,只需要将它连接到一个LWP上便可以具有内核支持线程的所有属性。
    ####系统实现
    Linux线程在核内是以轻量级进程存在的,拥有独立的进程表项,而所有的创建,同步和删除都在核外Pthread中实现的。Pthread库使用几个管理线程(Pthread_manager(),每个进程唯一)来管理线程的创建和终止,为线程分配ID,发送相关信号,而主线程(Pthread_create())的调用者则通过管道将请求信号传递给管理线程。
    Linux内核提供了两个系统调用_clone()和fork(),最终都用不同的参数调用do_fork()核内API。核心提供对多进程共享数据的支持,其实就是Light Weight Process(LWP)。创建进程使用fork系统调用,重量级进程。Pthread_create创建线程使用_clone()系统调用,轻量级进程。
    其实,最终Linux的线程和进程实际上处于一个调度层次,共享一个进程标识符空间(轻量级进程也是进程)。

程序作为进程的形式出现在操作系统中,相当于人生的青年阶段。这个阶段,程序开始建立档案,PCB和TCB等,为后续的程序执行打好坚实的基础,可以通过自己的竞争去争取处理器资源。社会也才把这个时间的人当作是一个社会的公民,可以自己为自己的行为负责任。如果犯法(出现异常),也是可以被kill掉的。
##链接和内存管理-壮年
##异常处理-老年

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值