第三章学习笔记

发布时间 2023-10-22 23:07:29作者: sjbdjb

第三章:Unix/Linux 进程管理

进程

操作系统是一个多任务处理系统。在操作系统中,任务也称作进程。在实际的应用中,任务和进程这两个术语可以互换使用。这里有一个关于执行映像的概念,我们把执行映像定义为包含执行代码、数据和堆栈的存储区。进程的正式定义:进程是对映像的执行

多任务处理系统

type.h文件

type.h文件定义了系统常数和表示进程的简单PROC结构体

 

ts.s文件

ts.s在32位gcc编码中可实现进程上下文切换

 queue.c文件

queue.c文件可实现队列和链表函数操作

 进程同步

睡眠模式

当某进程需要某些当前没有的东西时,例如申请独占一个存储区域、等待用户通过标准输入来输入字符等,它就会在某个事件值上进人休眠状态,该事件值表示休眠的原因。

对PROC结构体的修改如下

 唤醒操作

多个进程可能会进人休眠状态等待同一个事件,这是很自然的,因为这些进程可能都需要同一个资源,例如一台当前正处于繁忙状态的打印机。在这种情况下,所有这些进程都将休眠等待同一个事件值。当某个等待时间发生时,另一个执行实体(可能是某个进程或中断处理程序)将会调用kwakeup(even),唤醒正处于休眠状态等待该事件值的所有程序。如果没有任何程序休眠等待该程序,kwakeupO就不工作,即不执行任何操作。注意,被唤醒的进程可能不会立即运行。它只是被放入readyQueue中,排队等待运行。当被唤醒的进程运行时,如果它在休眠之前正在试图获取资源,那么它必须尝试重新获取资源。这是因为该资源在它运行时可能不再可用。ksleepO和kwakeupO函数一般用于进程同步,但在特殊情况下也用于同步父进程和子进程

进程终止

    • 正常终止:进程调用exit(value),发出_exit(value)系统调用来执行在操作系统内核
      中的kexit(value),这就是我们本节要讨论的情况。
    • 异常终止:进程因某个信号而异常终止。信号和信号处理将在后面第6章讨论。在这两种情况下,当进程终止时,最终都会在操作系统内核中调用kexi()。

 等待子进程中止

所谓父子进程,子进程是由父进程创建的完全独立于父进程的一个进程,父子进程共享一段代码和数据,子进程相当于父进程的副本

我们需要注意fork进程的返回值,在父子进程中有所不同。

 Unix/Linux中的进程

中断:中断是外部设备发送给CPU的信号,请求CPU服务。当在Umodie下执行时,CPU中断是启用的,因此它将响应任何中断。在中断发生时,CPU将进入Kmode来处理中断,这将导致进程进人Kmode。
陷附:陷是错误条件,例如无效地址、非法指令、陈以0等、这些错误条件被CPU识别为异常,使得CPU进人Kmode来处理错误。在Unix/Linux中,内核陷阴处理程序将陷研原因转换为信号编号,并将信号传递给进程。对于大多数信号,进程的默认操作是终止。
系统调用:系统调用(简称syscall)是一种允许Umode进程进入Kmode以执行内核函数的机制。当某进程执行完内核函数后,它将期望结果和一个返回值返回到Umode,该值通常为0(表示成功)或-1(表示错误)。如果发生错误,外部全局变量errno(在erno.h中)会包含一个ERROR代码,用于标识错误。

运行状态
进程的任务是由CPU执行的,进程需要从内存载入CPU才能运行,因此,进程的运行状态通常会被误认为是当一个进程占有CPU资源并执行其任务时的状态,其实不然。内存中的进程有多个,而CPU往往只有一个,为了保证每个进程都能运行,CPU在内核中有一个对应的等待队列,进程的PCB会进入到这个队列中等待CPU资源准备运行,而进程PCB在CPU等待队列中准备运行的状态就称运行状态。

阻塞状态
进程运行过程中,除了需要占有CPU资源,有时候也需要其他资源(下面拿外设资源来举例),如显示器、磁盘、网卡和键盘等等。因此各种外设资源也需要在内核中有自己的等待队列,供进程排队等待资源的占有使用。我们知道,操作系统通过先描述再组织的方式管理外设,在内核中为每个外设建立了一个结构体存储其属性、信息、操作方法等,类似进程的PCB,而外设的等待队列也就在该结构体当中。

挂起状态
挂起是操作系统节省内存空间一种手段。给一个场景:若在某一时刻内存中有多个进程处于阻塞状态,正在等待某种资源的就绪,这些进程的代码数据都在内存中保存着,短期内不会被使用。随着阻塞状态的进程数量增多,内存可能会空间不足。既然这些进程的代码数据暂时不会被使用,何不将它们移出内存呢?
操作系统是这样做的:将处于阻塞状态的进程的代码数据暂时移出内存,重新挪动到磁盘上,而该进程的PCB依然留存在内存中的资源等待队列,待到资源就绪之时,再通过PCB找到相应的代码数据,从磁盘中再加载入内存。

以上操作我们称其为进程代码数据的换入换出操作,节省了内存空间,供正在运行的进程使用。而挂起状态就是进程代码数据被暂时换出到磁盘上的状态。

Linux的各种进程状态:R (running):运行状态,并不一定意味着正在运行,它要么表示进程正在运行要么表示进程在运行队列中等候。

S(sleeping):睡眠状态,意味着进程在等待事件完成,对应阻塞状态。

D(disk sleep):磁盘休眠状态,有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束,IO结束前不会被操作系统自动回收。

T(stopped):停止状态,可以通过发送SIGSTOP信号(kill -19)使进程停止运行,也可以发送SIGCONT(kill -18)信号使进程继续运行。

X(dead):死亡状态,这个状态只是一个返回状态,你不会在任务列表里看到这个状态,因此当一个进程变成死亡状态时,操作系统会立即或延时将其回收。

Linux系统中的管道编程

 

 问题解决(gpt4.0)

 

 

 苏格拉底问答

 代码实现