2019-02-02 17:27:28 qq_38499859 阅读数 1608

操作系统3 ————进程控制块(PCB)详解

一.目录

二. 进程控制块

1.概述

进程控制块(Processing Control Block),是操作系统核心中一种数据结构,主要表示进程状态,其作用是使一个程序成为一个能够独立运行的基本单位,并且可以并发执行的进程。或者说,OS是根据PCB来对并发执行的进程进行控制和管理。PCB通常是占用系统内存中一块连续的内存空间,存放着操作系统用于描述进程情况及控制进程运行的全部信息。

2.进程控制块中的信息

a.进程标识符

  • 内部标识符:操作系统为每一个进程赋予的唯一数字标识符,系统使用
  • 外部标识符:由创建者提供,通常有字母与数字组成,往往是由用户(进程)在访问该进程时使用。描述进程的家族关系,设置父进程标识及子进程标识,还可设置用户标识,以指示拥有该进程的用户。

b.处理机状态

  • 主要是由处理机的各种寄存器中的内容组成的,处理机被中断时,所有这些信息都必须保存在PCB中,以便在该进程重新执行时,能从断点继续执行。
    这些寄存器包括: 通用寄存器、指令计数器、程序状态字PSW、用户栈指针

c.进程调度信息

  • 进程状态
  • 进程优先级
  • 进程调度所需要的其他信息,比如已等待CPU的时间综合,进程一直想的时间总和。
  • 事件,指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因

d.进程控制信息

  • 程序和数据的地址
  • 进程同步和通信机制
  • 资源清单
  • 链接指针

3.进程控制块的作用

PCB 可以被操作系统中的多个模块读或修改,如被调度程序、资源分配 程序、中断处理程序以及监督和分析程序等读或修改。 OS是根据 PCB来对 并发执行的进程进行控制和管理,所以说PCB是操作系统中最重要的记录型数据结构
其作主要作用如下:

1、作为独立运行基本单位的标志
2、能实现间断性运行方式
3、提供进程管理所需要的信息
4、提供进程调度所需要的信息
5、实现与其他进程的同步与通信

4.进程控制块的组织方式

a.线性方式: 即将系统中所有的PCB都组长在一张线性表中,将该表的首地址存放在内存的一个专用区域中。适合于系统中进程数目不多的情况
这里写图片描述
**b.链接方式:**该方式是线性表方式的改进,系统按照进程的状态分别建立就绪索引表、阻塞索引表等。
这里写图片描述
**c.索引方式:**系统按照进程的状态将进程的PCB组成队列,从而形成就绪队列、阻塞队列、运行队列等。
这里写图片描述

三.Linux的进程控制块

1.概述

Linux的进程控制块为一个由结构task_struct所定义的数据结构,task_struct存于/include/linux/sched.h 中,其中包括管理进程所需的各种信息。它会被装载到RAM⾥并且包含着进程的信息。所有运行在系统里的进程都以task_struct链表的形式存在内核里。

2.task_struct数据结构简述



    struct task_struct  

    {  

        long state; /*任务的运行状态(-1 不可运行,0 可运行(就绪),>0 已停止)*/  

        long counter;/*运行时间片计数器(递减)*/  

        long priority;/*优先级*/  

        long signal;/*信号*/  

        struct sigaction sigaction[32];/*信号执行属性结构,对应信号将要执行的操作和标志信息*/  

        long blocked; /* bitmap of masked signals */  

        /* various fields */  

        int exit_code;/*任务执行停止的退出码*/  

        unsigned long start_code,end_code,end_data,brk,start_stack;/*代码段地址 代码长度(字节数) 

                                        代码长度 + 数据长度(字节数)总长度 堆栈段地址*/  

        long pid,father,pgrp,session,leader;/*进程标识号(进程号) 父进程号 父进程组号 会话号 会话首领*/  

        unsigned short uid,euid,suid;/*用户标识号(用户id) 有效用户id 保存的用户id*/  

        unsigned short gid,egid,sgid; /*组标识号(组id) 有效组id 保存的组id*/  

        long alarm;/*报警定时值*/  

        long utime,stime,cutime,cstime,start_time;/*用户态运行时间 内核态运行时间 子进程用户态运行时间 

                               子进程内核态运行时间 进程开始运行时刻*/  

        unsigned short used_math;/*标志:是否使用协处理器*/  

        /* file system info */  

        int tty; /* -1 if no tty, so it must be signed */  

        unsigned short umask;/*文件创建属性屏蔽位*/  

        struct m_inode * pwd;/*当前工作目录i 节点结构*/  

        struct m_inode * root;/*根目录i节点结构*/  

        struct m_inode * executable;/*执行文件i节点结构*/  

        unsigned long close_on_exec;/*执行时关闭文件句柄位图标志*/  

        struct file * filp[NR_OPEN];/*进程使用的文件表结构*/  

        /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */  

        struct desc_struct ldt[3];/*本任务的局部描述符表。0-空,1-代码段cs,2-数据和堆栈段ds&ss*/  

        /* tss for this task */  

        struct tss_struct tss;/*本进程的任务状态段信息结构*/  

    };  

四.Unix的进程控制块

1.概述

在UNIX系统Ⅴ中,把进程控制块(PCB)分为四部分:

  • 进程表项,其中包括最常用的核心数据。
  • U区,用于存放用户进程表项的一些扩充数据。
  • 系统区表,存放各个区在物理存储器中的地址信息等。
  • 进程区表,用于存放各区的起始虚地址及指向系统区表中对应区表项的指针。

2.进程表项(Proc表)

用于描述和控制一个进程的信息通常都很多,其中有些是经常要被访问的,如进程标识符、进程状态等。为了提高对这些信息访问的效率,系统设计者将这些信息放在进程表项中,又称之为Proc表或Proc结构,使之常驻内存。在每个进程表项中,含有下述一些具体信息:

  1. 进程标识符(PID),也称内部标识符,为方便用户使用,这里惟一地标识一个进程的某个整数。
  2. 用户标识符(UID),标识拥有该进程的用户。
  3. 进程状态,表示该进程的当前状态。
  4. 事件描述符,记录使进程进入睡眠状态的事件。
  5. 进程和U区在内存或外存的地址,核心可利用这些信息做上、下文切换。
  6. 软中断信息,记录其它进程发来的软中断信号。
  7. 计时域,给出进程的执行时间和对资源的利用情况。
  8. 进程的大小,这是核心在为进程分配存储空间时的依据,包括正文段长度和栈段长度等。
  9. 偏置值nice,供计算该进程的优先数时使用,可由用户设置。
  10. P_Link指针,这是指向就绪队列中下一个PCB的指针。
  11. 指向U区进程正文、数据及栈在内存区域的指针。

3.U区

为了存放用于描述和控制进程的另一部分信息,系统为每一个进程设置了一个私用的U区,又称之为User结构,这部分数据并非常驻内存,其中含有下述信息:

  1. 进程表项指针,指向当前(正在执行)进程的进程表项。
  2. 真正用户标识符u-ruid(real user ID),这是由超级用户分配给用户的标识符,以后,每次用户在登录进入系统时,均须输入此标识符。
  3. 有效用户标识符u-euid(effective user ID),在一般情况下,它与ruid相同,但在其他用户允许的情况下,可用系统调用setuid将它改变为其他用户标识符,以获得对该用户的文件进行操作的权力。
  4. 用户文件描述符表,其中记录了该进程已打开的所有文件。
  5. 当前目录和当前根,用于给出进程的文件系统环境。
  6. 计时器,记录该进程及其后代在用户态和核心态运行的时间。
  7. 内部I/O参数,给出要传输的数据量、源(或目标)数据的地址、文件的输入/输出偏移量。
  8. 限制字段,指对进程的大小及其能“写”的文件大小进行限制。
  9. 差错字段,记录系统调用执行期间所发生的错误。
  10. 返回值,指出系统调用的执行结果。
  11. 信号处理数组,用于指示在接收到每一种信号时的处理方式。

4.系统区表

系统V把一个进程的虚地址划分为若干个连续的区域:正文区,数据区,栈区。这些去是可被共享和保护的独立实体,多个进程可以共享一个区,例如,多进程共享一个正文区,即几个进程将执行同一个(子)程序。同样,多个进程也可以进行共享一个数据区。为了对区进行管理。在核心设置了一个系统区表。在各表项中记录了以下有关描述活动区的信息:

  1. 区的类型和大小。
  2. 区的状态。一个区有这样几种状态: 锁住、在请求中、在装入过程、有效(区已装入内存)。
  3. 区在物理存储器中的位置。
  4. 引用计数,即共享该区的进程数。
  5. 指向文件索引结点的指针。

5.进程区表

为了记录进程的每个区在进程中的虚地址,并通过它找到该区在物理存储器中的实地址,系统为每个进程配置了一张进程区表。表中的每一项记录一个区的起始虚地址及指向系统区表中对应的区表项的指针。这样,核心可通过查找进程区表和系统区表,将区的逻辑地址变换为物理地址。可见,进程区表和系统区表用于对区地址进行映像(射)。这里用两张区表实现地址映射,是为了便于实现对区的共享。

五.windows的进程控制块

1.概述

在windows中执进程控制块是由 EPROCESS 块来表示的。 EPROCESS 块位于内核层之上,它侧重于提供各种管理策略,同时为上层应用程序提供基本的功能接口。所以,在执行体层的进程和线程数据结构中,有些成员直接对应于上层应用程序中所看到的功能实体。

2.EPROCESS的数据结构

typedef struct _EPROCESS 
{
    KPROCESS Pcb;  //KPROCESS被内核用来进行线程调度使用

    EX_PUSH_LOCK ProcessLock;//ProcessLock域是一个推锁(push lock)对象,用于保护EPROCESS中的数据成员。用来对可能产生的并行事件强制串行化。

    LARGE_INTEGER CreateTime; //这两个域分别代表了进程的创建时间和退出时间
    LARGE_INTEGER ExitTime; 

    EX_RUNDOWN_REF RundownProtect; //RundownProtect域是进程的停止保护锁,当一个进程到最后被销毁时,它要等到所有其他进程和线程已经释放了此锁,才可以继续进行,否则就会产生孤儿线程

    HANDLE UniqueProcessId;  //UniqueProcessId域是进程的唯一编号,在进程创建时就设定好了,我们在"任务管理器"中看到的PID就是从这个域中获取的值

    LIST_ENTRY ActiveProcessLinks; //ActiveProcessLinks域是一个双链表节点(注意是双链表中的一个节点),在windows系统中,所有的活动进程都连接在一起,构成了一个链表。

    SIZE_T QuotaUsage[PsQuotaTypes];//QuotaUsage和QuotaPeak域是指一个进程的内存使用量和尖峰使用量
    SIZE_T QuotaPeak[PsQuotaTypes];
    
    SIZE_T CommitCharge; //CommitCharge域中存储了一个进程的虚拟内存已提交的"页面数量"
    SIZE_T PeakVirtualSize;//PeakVirtualSize域是指虚拟内存大小的尖峰值。
    SIZE_T VirtualSize;//VirtualSize域是指一个进程的虚拟内存大小。

    LIST_ENTRY SessionProcessLinks;//SessionProcessLinks域是一个双链表节点,当进程加入到一个系统会话中时,这个进程的SessionProcessLinks域将作为一个节点(LIST_ENTRY在内核中很常见)加入到该会话的进程链表中。

    PVOID DebugPort; //DebugPort和ExceptionPort域是两个句柄(指针),分别指向当前进程对应的调试端口和异常端口。
    PVOID ExceptionPort;
    
    PHANDLE_TABLE ObjectTable; //ObjectTable域是当前进程的句柄表。

    EX_FAST_REF Token; //Token域是一个快速引用,指向该进程的访问令牌,用于该进程的安全访问检查。

    PFN_NUMBER WorkingSetPage;  //WorkingSetPage域是指包含进程工作集的页面
    KGUARDED_MUTEX AddressCreationLock;//AddressCreationLock域是一个守护互斥体锁(guard mutex),用于保护对地址空间的操作。
    KSPIN_LOCK HyperSpaceLock;//HyperSpaceLock是一个自旋锁,用于保护进程的超空间

    struct _ETHREAD *ForkInProgress;//ForkInProgress指向正在复制地址空间的那个线程,仅当在地址空间复制过程中,此域才会被赋值,在其他情况下为NULL。
    ULONG_PTR HardwareTrigger;//HardwareTrigger用于记录硬件错误性能分析次数

    PMM_AVL_TABLE PhysicalVadRoot;//PhysicalVadRoot域指向进程的物理VAD的根。它并不总是存在,只有当确实需要映射物理内存时才会被创建。
    PVOID CloneRoot;//CloneRoot指向一个平衡树的根,当进程地址空间复制时,此树被创建,创建出来后,一直到进程退出的时候才被销毁。CloneRoot域完全是为了支持fork语义而引入。
    PFN_NUMBER NumberOfPrivatePages;//指进程私有页面的数量
    PFN_NUMBER NumberOfLockedPages;//指进程被锁住的页面的数量
    PVOID Win32Process;//Win32Process域是一个指针,指向由windows子系统管理的进程区域,如果此值不为NULL,说明这是一个windows子系统进程(GUI进程)
    struct _EJOB *Job;//对于job域,只有当一个进程属于一个job(作业)的时候,它才会指向一个_EJOB对象。
    PVOID SectionObject;//SectionObject域也是一个指针,代表进程的内存去对象(进程的可执行映像文件的内存区对象)

    PVOID SectionBaseAddress;// SectionBaseAddress域为该内存区对象的基地址

    PEPROCESS_QUOTA_BLOCK QuotaBlock;//QuotaBlock域指向进程的配额块,进程的配额块类型为: EPROCESS_QUOTA_BLOCK

    PPAGEFAULT_HISTORY WorkingSetWatch;//WorkingSetWatch域用于监视一个进程的页面错误,一旦启用了页面错误监视功能(由全局变量PsWatchEnabled开关来控制),则每次发生页面错误都会将该页面错误记录到WorkingSetWatch域的WatchInfo成员数组中,知道数组满为止。
    HANDLE Win32WindowStation;//Win32WindowStation域是一个进程所属的窗口站的句柄。由于句柄的值是由每个进程的句柄表来决定的,所以,两个进程即使同属于一个窗口站,它们的Win32WindowStation也可能不同,但指向的窗口站对象是相同的。窗口站是由windows子系统来管理和控制的。
    HANDLE InheritedFromUniqueProcessId;//InheritedFromUniqueProcessId域说明了一个进程是从哪里继承来的,即父进程的标识符。

    PVOID LdtInformation;//LdtInformation用来维护一个进程的LDT(局部描述符表)信息。
    PVOID VadFreeHint;//VadFreeHint域指向一个提示VAD(虚拟地址描述符)节点,用于加速在VAD树中执行查找操作。
    PVOID VdmObjects;//VdmObjects域指向当前进程的VDM数据区,其类型为VMD_PROCESS_OBJECTS,进程可通过NtVdmControl系统服务来初始化VDM。
    PVOID DeviceMap;//DeviceMap域指向进程使用的设备表,通常情况下同一个会话中的进程共享同样的设备表。

    PVOID Spare0[3];//Spare0域是一个备用域
    union //页表项
    {
        HARDWARE_PTE PageDirectoryPte;
        ULONGLONG Filler;
    };
    PVOID Session;//Session指向进程所在的系统会话,实际上它是一个指向MM_SESSION_SPACE的指针。\base\ntos\mm\mi.h 中相关的结构体定义
    UCHAR ImageFileName[ 16 ];//ImageFileName域包含了进程的映像文件名,仅包含最后一个路径分隔符之后的字符串,不超过16字节。

    LIST_ENTRY JobLinks;//JobLinks域是一个双链表节点,通过此节点,一个job中的所有进程构成了一个链表。在windows中,所有的job构成了一个双链表,其链表头为全局变量PspJobList。每个job中的进程又构成了一个双链表。
    PVOID LockedPagesList;//LockedPagesList域是一个指向LOCK_HEADER结构的指针,该结构包含了一个链表头,windows通过此链表来记录哪些页面已被锁住(这里所谓的锁住和Mdll中的映射机制有关,本质上就是把用户空间下的内存地址锁定到内核空间中以便访问)

    LIST_ENTRY ThreadListHead; //ThreadListHead域是一个双链表的"头结点",该链表中包含了一个进程中的所有"线程"。

    PVOID SecurityPort; //SecurityPort域是一个安全端口,指向该进程域lsass.exe进程之间的跨进程通信端口。
    PVOID PaeTop; //PaeTop域用于支持PAE内存访问机制。

    ULONG ActiveThreads;//ActiveThreads域记录了当前进程有多少活动线程。当该值减为0时,所有的线程将退出,于是进程也退出。

    ACCESS_MASK GrantedAccess;//GrantedAccess域包含了进程的访问权限,访问权限是一个"位组合"。 public\sdk\inc\ntpsapi.h 中的宏 PROCESS_XXX

    ULONG DefaultHardErrorProcessing;//DefaultHardErrorProcessing域指定了默认的硬件错误处理,默认为1

    NTSTATUS LastThreadExitStatus; //LastThreadExitStatus域记录了刚才最后一个线程的退出状态。

    PPEB Peb; //Peb域是一个进程的"进程环境块

    EX_FAST_REF PrefetchTrace;//PrefetchTrace域是一个快速引用,指向与该进程关联的一个"预取痕迹结构",以支持该进程的预取。
    LARGE_INTEGER ReadOperationCount;//ReadOperationCount,WriteOperationCount记录了当前进程NtReadFile和NtWriteFile系统服务被调用的次数,OtherOperationCount记录了除读写操作以外的其他IO服务的次数(文件信息设置.)
    LARGE_INTEGER WriteOperationCount;
    LARGE_INTEGER OtherOperationCount;
    LARGE_INTEGER ReadTransferCount;//ReadTransferCount,WriteTransferCount记录了IO读写操作"完成"的次数,OtherTransferCount记录了除读写操作以外操作完成的次数。
    LARGE_INTEGER WriteTransferCount;
    LARGE_INTEGER OtherTransferCount;

    SIZE_T CommitChargeLimit;
    SIZE_T CommitChargePeak;

    PVOID AweInfo; //AweInfo域是一个指向AWEINFO结构的指针,其目的是支持AWE(Adress Windowing Extension 地址窗口扩展)

    SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo;//SeAuditProcessCreationInfo域包含了创建进程时指定的进程映像全路径名

    MMSUPPORT Vm;//Vm域是windows为每个进程管理虚拟内存的重要数据结构成员,其类型为MMSUPPORT, \base\ntos\inc\ps.h 中有相关定义
 
    LIST_ENTRY MmProcessLinks; //MmProcessLinks域代表一个双链表节点,所有拥有自己地址空间的进程都将加入到一个双链表中,链表头是全局变量MmProcessList

    ULONG ModifiedPageCount; //ModifiedPageCount域记录了该进程中已修改的页面的数量,即"脏页面数量",这和缓存的读写有关。

    ULONG JobStatus; //49. ULONG JobStatus

JobStatus域记录了进程所属job的状态。
 
    union //Flags域包含了进程的标志位,这些标志位反映了进程的当前状态和配置。  \base\ntos\inc\ps.h 中的宏定义 PS_PROCESS_FLAGS_XXX
    { 
        ULONG Flags; 

        struct {
            ULONG CreateReported            : 1;
            ULONG NoDebugInherit            : 1;
            ULONG ProcessExiting            : 1;
            ULONG ProcessDelete             : 1;
            ULONG Wow64SplitPages           : 1;
            ULONG VmDeleted                 : 1;
            ULONG OutswapEnabled            : 1;
            ULONG Outswapped                : 1;
            ULONG ForkFailed                : 1;
            ULONG Wow64VaSpace4Gb           : 1;
            ULONG AddressSpaceInitialized   : 2;
            ULONG SetTimerResolution        : 1;
            ULONG BreakOnTermination        : 1;
            ULONG SessionCreationUnderway   : 1;
            ULONG WriteWatch                : 1;
            ULONG ProcessInSession          : 1;
            ULONG OverrideAddressSpace      : 1;
            ULONG HasAddressSpace           : 1;
            ULONG LaunchPrefetched          : 1;
            ULONG InjectInpageErrors        : 1;
            ULONG VmTopDown                 : 1;
            ULONG ImageNotifyDone           : 1;
            ULONG PdeUpdateNeeded           : 1;    // NT32 only
            ULONG VdmAllowed                : 1;
            ULONG SmapAllowed               : 1;
            ULONG CreateFailed              : 1;
            ULONG DefaultIoPriority         : 3;
            ULONG Spare1                    : 1;
            ULONG Spare2                    : 1;
        };
    };

    NTSTATUS ExitStatus;//ExitStatus域包含了进程的退出状态,从进程的退出状态通常可以获知进程非正常退出的大致原因。反映退出状态的一些宏定义位于 public\sdk\inc\ntstatus.h

    USHORT NextPageColor;//NextPageColor域用于物理页面分配算法。
    union 
    {
        struct 
    {
            UCHAR SubSystemMinorVersion;
            UCHAR SubSystemMajorVersion;
        };
        USHORT SubSystemVersion;
    };
    UCHAR PriorityClass;//PriorityClass域是一个单字节值,它说明了一个进程的优先级程度

    MM_AVL_TABLE VadRoot;//VadRoot域指向一个平衡二叉树的根,用于管理该进程的虚拟地址空间。

    ULONG Cookie;//Cookie域存放的是一个代表该进程的随机值,当第一次通过NtQueryInformationProcess函数获取此Cookie值的时候,系统会生成一个随机值,以后就用此值代表此进程

} EPROCESS, *PEPROCESS; 

六.参考资料

《计算机操作系统第四版》
EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)
Unix进程描述(进程控制块pcb的内容)
Linux下的进程控制块—task_struct

2017-03-05 15:48:05 qq_33544335 阅读数 2673

进程基本概念:进程的产生是因为为了使程序能并发执行,且为了对并发执行的程序加以描述和控制。
进程的结构:程序段、相关的数据段和 PCB (进程控制块Process Control Block)。
进程跟程序是不同的,进程是动态的,程序是动态的,进程有创建,执行,消亡,所以进程实体是有生命周期的,而程序只是一组有序指令的集合。
可以总结一下:
(1) 进程是程序的一次执行。
(2) 进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
(3) 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
最开始进程有三种状态:就绪,执行,阻塞。
状态间的转换如图:
Linux状态示意
(1) 活动就绪→静止就绪。当进程处于未被挂起的就绪状态时,称此为活动就绪状态,表示为 Readya。当用挂起原语 Suspend 将该进程挂起后,该进程便转变为静止就绪状态,表示为 Readys,处于 Readys 状态的进程不再被调度执行。
(2) 活动阻塞→静止阻塞。当进程处于未被挂起的阻塞状态时,称它是处于活动阻塞状态,表示为 Blockeda。当用 Suspend 原语将它挂起后,进程便转变为静止阻塞状态,表示为Blockeds。处于该状态的进程在其所期待的事件出现后,将从静止阻塞变为静止就绪。
(3) 静止就绪→活动就绪。处于 Readys 状态的进程,若用激活原语 Active 激活后,该进程将转变为 Readya 状态。
(4) 静止阻塞→活动阻塞。处于 Blockeds 状态的进程,若用激活原语 Active 激活后,该进程将转变为 Blockeda 状态。
这里写图片描述
再加上创建状态和终止状态:
创建一个进程一般要通过两个步骤:首先,为一个新进程创建 PCB,并填写必要的管理信息;其次,把该进程转入就绪状态并插入就绪队列之中。当一个新进程被创建时,系统已为其分配了 PCB,填写了进程标识等信息,但由于该进程所必需的资源或其它信息,如主存资源尚未分配等,一般而言,此时的进程已拥有了自己的 PCB,但进程自身还未进入主存,即创建工作尚未完成,进程还不能被调度运行,其所处的状态就是创建状态。
进程的终止也要通过两个步骤:首先等待操作系统进行善后处理,然后将其 PCB 清零,并将 PCB 空间返还系统。当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止状态。进入终止态的进程以后不能再执行,但在操作系统中依然保留一个记录,其中保存状态码和一些计时统计数据,供其它进程收集。一旦其它进程完成了对终止状态进程的信息提取之后,操作系统将删除该进程。
进程控制块:
为了描述和控制进程的运行,系统为每个进程定义了一个数据结构——进程控制块PCB(Process Control Block),它是进程实体的一分,PCB是进程存在的唯一标志。 Linux 系统中用task_struct 数据结构来描述每个进程的进程控制块,在 Windows 操作系统中则使用一个执行体进程块(EPROCESS)来表示进程对象的基本属性。
PCB中包括:
1.进程标识符:进程标识符用于惟一地标识一个进程。一个进程通常有两种标识符:内部标识符,外部标识符。
内部标识符。在所有的操作系统中,都为每一个进程赋予了一个惟一的数字标识符,它通常是一个进程的序号。
外部标识符。它由创建者提供,通常是由字母、数字组成,往往是由用户(进程)在访问该进程时使用。
2.处理机状态:处理机状态信息主要是由处理机的各种寄存器中的内容组成的。处理机在运行时,许多信息都放在寄存器中。当处理机被中断时,所有这些信息都必须保存在 PCB 中,以便在该进程重新执行时,能从断点继续执行。这些寄存器包括:
① 通用寄存器,又称为用户可视寄存器,它们是用户程序可以访问的,用于暂存信息,在大多数处理机中,有 8~32 个通用寄存器,在 RISC 结构的计算机中可超过 100 个;
② 指令计数器,其中存放了要访问的下一条指令的地址;
③ 程序状态字 PSW,其中含有状态信息,如条件码、执行方式、中断屏蔽标志等;
④ 用户栈指针,指每个用户进程都有一个或若干个与之相关的系统栈,用于存放过程和系统调用参数及调用地址,栈指针指向该栈的栈顶。
3.进程调度信息:
在 PCB 中还存放一些与进程调度和进程对换有关的信息,包括:
① 进程状态,指明进程的当前状态,作为进程调度和对换时的依据;
② 进程优先级,用于描述进程使用处理机的优先级别的一个整数,优先级高的进程应优先获得处理机;
③ 进程调度所需的其它信息,它们与所采用的进程调度算法有关,比如,进程已等待 CPU 的时间总和、进程已执行的时间总和等;
④ 事件,指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。
4.进程控制信息包括:
① 程序和数据的地址,指进程的程序和数据所在的内存或外存地(首)址,以便再调度到该进程执行时,能从 PCB 中找到其程序和数据;
② 进程同步和通信机制,指实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能全部或部分地放在 PCB 中;
③ 资源清单,即一张列出了除 CPU 以外的、进程所需的全部资源及已经分配到该进程的资源的清单;
④ 链接指针,它给出了本进程(PCB)所在队列中的下一个进程的 PCB 的首地址。
PCB的组织方式:
链接方式:这是把具有同一状态的 PCB,用其中的链接字链接成一个队列。这样,可以形成就绪队列、若干个阻塞队列和空白队列等。对其中的就绪队列常按进程优先级的高低排列,把优先级高的进程的 PCB 排在
队列前面。此外,也可根据阻塞原因的不同而把处于阻塞状态的进程的 PCB 排成等待 I/O 操作完成的队列和等待分配内存的队列等。
这里写图片描述
索引方式:系统根据所有进程的状态建立几张索引表。例如,就绪索引表、阻塞索引表等,并把各索引表在内存的首地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个 PCB 在 PCB 表中的地址。
这里写图片描述

2018-10-14 20:33:54 qq_40310816 阅读数 32

课前问题:

1.允许并发是不是说多道程序可随便交替执行?

答:并发程序执行时具有不确定性(如果结果不确定,那程序将毫无意义),因此所谓并发应是“有控制的并发”,“能控制且合理控制的并发”

2.操作系统怎么管理多道并发程序?

答:用进程管理,进程有三种状态,就绪·执行和阻塞,而这些信息都记录在进程控制块PCB中,因此操作系统首先查看PCB获取状态,然后调度

3.操作系统怎么知道有几个进程可运行?又怎么知道哪个程序运行不下去需要换人了?操作系统怎么知道要运行的程序在哪里?

答:通过查看PCB

笔记

引入概念:
前趋图:是指一个有向无循环图,可记为DAG(Directed Acyclic Graph),它用于描述进程之间的先后顺序(图中每个节点可用来表示一个进程或程序段,乃至一条语句,节点间的有向边则表示两个节点之间存在的偏序或前驱关系)

程序顺序执行时的特征:

  1. 顺序性
  2. 封闭性(程序一旦执行,其结果不受外界因素影响)
  3. 可再现性(程序只要初始条件一样,不论如何停顿,结果保持不变)

并发程序执行时的特征:

  1. 间断性
  2. 失去封闭性(程序会受其他程序影响–需要争抢资源)
  3. 不可再现性
    <–结果不确定,程序执行将毫无意义,因此多道并发是有控制的并发,要能控制并且合理控制–>
    错误并发:

例如两个独立的程序A、B,正好使用了同一内存变量空间:
程序A:每执行一次都做a+1;
程序B:每隔一定时间Print b,b=0。
设两者都要循环10次,则:
A的角度看,执行10次,结果应为10
B的角度看,执行10次,结果都应为0
并发交替执行可能的结果:
– 如果执行2次时被B操作了N,那么结果为8;
– 如果执行7次后才被B影响了N,结果为3;
没有任何干预下,会出现结果不可再现的并发,即错误的并发。

进程
程序:程序段+数据段(按事先设计的功能和性能要求执行的指令序列)。
进程实体:程序段+数据段+PCB
PCB(Process Control Block):进程控制块–存放进程的管理和控制信息的数据结构,

进程:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位

进程的特征

1.结构性特征,进程的根本——PCB
2.动态性
<1>进程实质上是进程实体的一次有生命期的执行过程。程序只是静态的一组有序指令。
<2>进程最基本特征
3.并发性
<1>多个进程实体同存于内存中,在一段时间内同时运行。
<2>有PCB的程序才能并发。
4.独立性
5.异步性

各进程相关的共享资源:cpu·存储器·I/O设备·时间片(这些资源在进程状态变化中对进程运行有影响)

进程的三种基本状态

(1)就绪状态(Ready)
进程获得除CPU之外的所有必需资源,一旦得到CPU控制权,可立即运行。
(2)运行状态(Running)
进程已获得所有运行必需的资源,正在处理机上执行。
(3)阻塞状态(Blocked)
正在执行的进程由于发生某事件(请求I/O、申请缓冲、时间片到)而暂时无法执行时,便放弃CPU后暂停

在这里插入图片描述

注意:
单处理机系统,执行态的进程只有一个
就绪态、阻塞态的进程可有多个。一般讲它们分别排称一个队列,称就绪队列、阻塞队列。
阻塞队列有的会根据不同原因再排成多个队列。

2017-04-02 23:03:16 J_Max 阅读数 254

一、了解PCB
操作系统具有三大功能:进程管理、内存管理以及文件系统。其核心当属进程管理。那么何为进程呢?详情请度娘。如果还是不解,那么按下Ctrl+Alt+Delete进入任务管理器,这下便一目了然。简单来说进程就是在运行的程序。
这里写图片描述
操作系统好比一个城市,进程就像来来往往的人群。我们会用很多的词汇来描述一个人。高的,矮的,胖的,瘦的等等。那么,我们用什么东西来描述一个进程呢?答案是进程控制块PCB—-task struct。进程控制块是一个很庞大的数据结构(详情可点击1234-1664)。
如下图
网络图片
Linux进程的状态与操作系统原理中的描述的进程状态似乎有所不同,比如就绪状态和运行状态都是TASK_RUNNING,但是又存在不同。在PCB中使用state;来描述进程的状态 (-1 unrunnable, 0 runnable, >0 stopped
这里写图片描述
PCB用来描述相关堆栈的属性
这里写图片描述
PCB用pid,tgid来区分不同的进程。
这里写图片描述
所有的进程都通过一个双向链表来链接。
这里写图片描述
这里写图片描述
PCB用来描述和当前任务CPU相关的状态
这里写图片描述

二、生生不息
在第三周的课程中,start_kernel的最后一句是rest_init(),在rest_init()中,创建了1号进程(所有用户态进程祖先)和2号进程(所有内核线程的祖先)
这里写图片描述
用户态通过fork()函数来创建一个新的进程,这看似简单的一个系统调用,实则暗藏玄机。 fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。
这里写图片描述
接着执行copy_process,然后再copy_process中再进行复制PCB操作。
这里写图片描述
在一系复制操作完成后,子进程会进行一些初始化的操作。
这里写图片描述
三、实验与分析

实验目的:使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone
实验步骤:
    rm menu -rf
git clone https://github.com/mengning/menu.git

cd menu
mv test_fork.c test.c
make rootfs


qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb调试
gdb
file linux-3.18.6/vmlinux    
target remote:1234
设置断点
b sys_clone
b do_fork
b dup_task_struct
b copy_process
b copy_thread
b ret_from_fork

四、总结
创建一个新进程在内核中的执行过程 fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建,之后子类进行相关初始化。修改复制过来的进程数据,比如pid、进程链表等等
复制内核堆栈
这里写图片描述

*childregs = *current_pt_regs(); //复制内核堆栈
p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

Linux内核分析

                                    written by
                                     江明星
没有更多推荐了,返回首页