操作系统实验报告

操作系统实验报告

                                 

          

20##年12月25日


实验一 线程的状态和转换(5分)

1 实验目的和要求

目的:熟悉线程的状态及其转换,理解线程状态转换与线程调度的关系。

要求:

(1)跟踪调试EOS线程在各种状态间的转换过程,分析EOS中线程状态及其转换的相关源代码;

(2)修改EOS的源代码,为线程增加挂起状态。

2 完成的实验内容

2.1 EOS线程状态转换过程的跟踪与源代码分析

(分析EOS中线程状态及其转换的核心源代码,说明EOS定义的线程状态以及状态转换的实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等)

EOS定义的线程状态在ps/psp.h的THREAD_STATE枚举中,包含Zero(线程状态转换过程中的中间状态)、Ready(就绪)、Running(运行)、Waiting(等待)、Terminated (结束)。

线程在不同的状态间相互转换时,通过调用ps/sched.c文件中的下面几个函数完成:PspReadyThread(将指定线程插入其优先级对应的就绪队列的队尾,并修改其状态码为Ready)、PspUnreadyThread(将指定线程从就绪队列中移除,并修改其状态码为Zero)、PspWait(将当前运行线程插入指定等待队列的队尾,并修改状态码为Waiting,然后执行线程调度)、PspUnwaitThread(将阻塞线程从其所在的等待队列中移除,并修改其状态码为Zero)、PspWakeThread(调用PspUnwaitThread 函数使线程脱离阻塞状态,然后调用PspReadyThread函数使线程进入就绪状态,从而唤醒被阻塞的线程)、PspSelectNextThread(使被抢先的线程从运行状态进入就绪状态,并决定哪个就绪线程应该进入运行状态)。

实验中通过对上述函数添加断点,通过EOS的loop命令观察线程状态的变化、使用pt命令查看各线程状态。

2.2为线程增加挂起状态的实现

(给出实现方法的简要描述、源代码、测试和结果等)

在psp.h中为THREAD_STATE添加Hang作为挂起状态的标志:

typedef enum _THREAD_STATE {

            Zero,                 // 0

            Ready,              // 1

            Running,           // 2

            Waiting,            // 3

            Terminated,       // 4

            Hang        // 5

} THREAD_STATE;

修改psspng.c中PsSuspendThread函数如下:

{

            STATUS Status;

            BOOL IntState;

            PTHREAD Thread;

            Status = ObRefObjectByHandle(hThread, PspThreadType, (PVOID*)&Thread);

            if (EOS_SUCCESS(Status)) {

                        IntState = KeEnableInterrupts(FALSE);

                        if (Ready == Thread->State) {

                                    PspUnreadyThread(Thread);

                                    Thread->State = Hang; //修改为挂起状态

                                    ListInsertTail(&SuspendListHead, &Thread->StateListEntry);

                                    Status = STATUS_SUCCESS;

                        } else {

                                    Status = STATUS_NOT_SUPPORTED;

                        }

                        KeEnableInterrupts(IntState);

                        ObDerefObject(Thread);

            }

            return Status;

}

修改PsResumThread函数如下:

            STATUS Status;

            BOOL IntState;

            PTHREAD Thread;

            Status = ObRefObjectByHandle(hThread, PspThreadType, (PVOID*)&Thread);

            if (EOS_SUCCESS(Status)) {

                        IntState = KeEnableInterrupts(FALSE);

                        if (Hang == Thread->State) {

Thread->State = Zero; //恢复为zero状态

                                    ListRemoveEntry(&Thread->StateListEntry); //从挂起列队删除

                                    PspReadyThread(Thread); //加入到就绪列队

                                    PspThreadSchedule(); //调度线程

                                   

                                    Status = STATUS_SUCCESS;

                        } else {

                                    Status = STATUS_NOT_SUPPORTED;

                        }

                        KeEnableInterrupts(IntState);

                        ObDerefObject(Thread);

            }

            return Status;

}

在sysproc.c中修改ConsoleCmdProcAndThread函数为pt命令添加Hang显示:

            switch(pThread->State) {

                        case Zero:

                                    ThreadState = "Zero      ";

                                    break;

                        case Ready:

                                    ThreadState = "Ready     ";

                                    break;

                        case Running:

                                    ThreadState = "Running   ";

                                    break;

                        case Waiting:

                                    ThreadState = "Waiting   ";

                                    break;

                        case Terminated:

                                    ThreadState = "Terminated";

                                    break;;

                        case Hang:

                                    ThreadState = "Hang";

                                    break;;

                        default:

                                    ThreadState = "Undefined ";

            }

测试用suspend命令挂起loop命令的线程后,loop的循环暂停。pt中查看loop的线程状态变为Hang。之后用resume命令恢复loop线程,循环恢复,pt中查看loop线程状态为Ready。

3 其他需要说明的问题

在pt中还列出了loop的31号线程以外的多个系统线程。其中loop线程状态不是Running而是Ready是因为EOS是单处理器系统,执行pt命令时pt的线程成为Running而loop线程进入就绪状态变为Ready。

EOS使用KeEnableInterrupts开关中断来实现原语操作。


实验二 进程的同步(7分)

1 实验目的和要求

目的:理解进程同步的原理和意义,掌握信号量的实现方法和应用。

要求:

(1)使用EOS的信号量,实现生产者-消费者问题;

(2)跟踪调试EOS信号量的工作过程,分析EOS信号量实现的源代码;

(3)修改EOS信号量的实现代码,使之支持等待超时唤醒和批量释放功能。

2 完成的实验内容

2.1 使用EOS的信号量实现生产者-消费者问题

(简要说明使用EOS的信号量解决生产者-消费者问题的实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪、测试与思考等)

EOS使用CreateThread函数创建线程,使用CreateMutex、CreateSemaphore创建信号量。WaitForSingleObject与ReleaseMutex、ReleaseSemaphore函数相当于P、V原语。

实验通过跟踪调试试验程序pc.c观察EOS的进程同步方法。pc.c实现的生产者-消费者如下图。

2.2 EOS信号量工作过程的跟踪与源代码分析

(分析EOS信号量实现的核心源代码,简要阐述其实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等)

EOS的P、V原语实现是PsWaitForSemaphore、PsReleaseSemaphore,这两个函数使用KeEnableInterrupts开关中断来实现原语操作。

EOS通过CreateMutex、CreateSemaphore创建信号量,有两种状态signaled和nonsignaled,线程对处于nonsignaled状态的同步对象执行Wait操作将会被阻塞,直到同步对象的状态变为signaled。

2.3支持等待超时唤醒和批量释放功能的EOS信号量实现

(给出实现方法的简要描述、源代码、测试和结果等)

修改PsWaitForSemaphore函数如下添加支持超时。

STATUS

PsWaitForSemaphore(

            IN PSEMAPHORE Semaphore,

            IN ULONG Milliseconds

            )

{

            BOOL IntState;

            ASSERT(KeGetIntNesting() == 0);

            IntState = KeEnableInterrupts(FALSE);

            STATUS ret;

            if (Semaphore->Count > 0) {

                        Semaphore->Count--;

                        ret = STATUS_SUCCESS;

            } else {

                        ret = PspWait(&Semaphore->WaitListHead, Milliseconds);

            }

            KeEnableInterrupts(IntState); /

            return ret;

}

修改PsReleaseSemaphore函数如下添加批量释放支持。

STATUS

PsReleaseSemaphore(

            IN PSEMAPHORE Semaphore,

            IN LONG ReleaseCount,

            OUT PLONG PreviousCount

            )

{

            STATUS Status;

            BOOL IntState;

            IntState = KeEnableInterrupts(FALSE);

            if (Semaphore->Count + ReleaseCount > Semaphore->MaximumCount) {

                        Status = STATUS_SEMAPHORE_LIMIT_EXCEEDED;

            } else {

                        if (NULL != PreviousCount) {

                                    *PreviousCount = Semaphore->Count;

                        }

                        int i;

                        for(i = ReleaseCount; i--;) {

                                    Semaphore->Count++;

                                    if (Semaphore->Count <= 0) {

                                                PspWakeThread(&Semaphore->WaitListHead, STATUS_SUCCESS);

                                    }

                        }

                        PspThreadSchedule();

                        Status = STATUS_SUCCESS;

            }

            KeEnableInterrupts(IntState);

            return Status;

}

修改后使用新的pc.c进行测试,生产者会提示“Producer wait for empty semaphore timeout”说明超时唤醒成功,消费者会提示“Consumer wait for full semaphore timeout"直到一次消费2个产品说明批量释放成功。

3 其他需要说明的问题


实验三 时间片轮转调度(5分)

1 实验目的和要求

目的:理解进程(线程)调度的执行时机和过程,掌握调度程序实现的基本方法。

要求:

(1)跟踪调试EOS的线程调度程序,分析EOS基于优先级的抢占式调度的源代码;

(2)修改EOS的调度程序,添加时间片轮转调度。

2 完成的实验内容

2.1 EOS基于优先级的抢占式调度工作过程的跟踪与源代码分析

(分析EOS基于优先级的抢占式调度的核心源代码,简要阐述其实现方法;给出在本部分实验过程中完成的主要工作,包括调试、跟踪与思考等)

实验使用EOS提供的rr命令观察时间片的轮转。

EOS创建一个PspReadyListHeads数组保存32个双向链表头实现有32个优先级的优先级队列管理。同时,EOS用PspReadyBitmap描述32位就绪位图来说明非空就绪列队。

EOS使用Interrupt函数进行统一的中断处理,在其中使用PspSelectNextThread函数完成线程的调度。调度过程如下图:

2.2EOS添加时间片轮转调度的实现

(给出实现方法的简要描述、源代码、测试和结果等)

修改PspRoundRobin函数如下:

VOID

PspRoundRobin(

            VOID

            )

{

            if (NULL == PspCurrentThread || Running != PspCurrentThread->State) {

                        return;

            }

            PspCurrentThread->RemainderTicks--;

           

            if(PspCurrentThread->RemainderTicks > 0) {

                        return;

            }

            PspCurrentThread->RemainderTicks = TICKS_OF_TIME_SLICE;

           

            if(0 == BIT_TEST(PspReadyBitmap, PspCurrentThread->Priority)) {

                        return;

            }

            PspReadyThread(PspCurrentThread);

            return;

}

修改后rr命令能够进行20个线程的轮转。

3 其他需要说明的问题

 

第二篇:操作系统实验报告三

《操作系统原理》实验报告

实验序号:  三        实验项目名称Windows基本进程管理

相关推荐