Ucore Lab7 操作系统实验

这篇实验报告详述了UCore Lab7中的操作,涉及内核级信号量的设计和哲学家就餐问题的解决。通过对比lab6与lab7的区别,分析了信号量在进程同步中的作用,包括信号量的P、V操作及其执行流程。报告还探讨了如何在用户态为进程提供信号量机制,并比较了与内核级信号量的异同。最后,通过条件变量和管程概念,解决了基于内核级条件变量的哲学家就餐问题。
摘要由CSDN通过智能技术生成

LAB7实验报告

实验相关知识

(主要从教学ppt、gitbook、学堂在线上了解掌握并根据CSDN查询了解更加详细的信息。同时结合自己的理论课笔记,实际上是对理论知识的复习

(此次实验理论知识较为抽象,需具体分析)


根据系统的设计,在语句执行期间,也有可能发生中断或调度,从而导致和当前进程无关的程序先一步执行。为了保证程序执行最终结果的正确性,必须对并发执行的各进程制约,以控制它们的执行速度和对资源的竞争。

互斥:一组并发进程中的一个或多个程序段,因为共享某一个公有资源而导致它们必须以一个不允许交叉执行的单位执行。即不允许两个以上的共享该资源的并发进程同时进入临界区称为互斥。

临界区(critical section):每个进程中访问临界资源的那段程序(临界资源是一次仅允许一个进程使用的共享资源。)每次只准许一个进程进入临界区,进入后不允许其他进程进入。不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。

互斥是指某一资源同时只允许一个进程对其进行访问,具有唯一性和排它性,但互斥不用限制进程对资源的访问顺序,即访问可以是无序的。同步是指在进程间的执行必须严格按照规定的某种先后次序来运行,即访问是有序的,这种先后次序取决于要系统完成的任务需求。在进程写资源情况下,进程间要求满足互斥条件。在进程读资源情况下,可允许多个进程同时访问资源。

算法进入临界区的准则:有空让进、无空等待、择一而入、算法可行(等待有限)

如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。信号允许多个线程同时使用共享资源,这与操作系统中的P V操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。信号量的关键之处在于它们原子地执行。必须确保没有两个进程能够同时对同一信号量执行wait和signal操作

P V 操作:P(sem):表示申请一个资源 V (sem):表示释放一个资源。信号量的初值应该大于等于0。P、V操作必须成对出现,有一个 P 操作就一定有一个 V 操作。

实验内容

  • 主要是熟悉 ucore的进程同步机制—信号量(semaphore)机制,以及基于信号量的哲学家就餐问题解决方案;
  • 掌握管程的概念和原理,并参考信号量机制,实现基于管程的条件变量机制和基于条件变量来解决哲学家就餐问题;

实验过程

练习1: 理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题(不需要编码)

完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件)个人完成的lab6和练习0完成后的刚修改的lab7之间的区别,分析了解lab7采用信号量的执行过程。执行make grade,大部分测试用例应该通过。

请在实验报告中给出内核级信号量的设计描述,并说其大致执行流流程。

请在实验报告中给出给用户态进程/线程提供信号量机制的设计方案,并比较说明给内核级提供信号量机制的异同。

答:分析lab6和lab7的区别可知,lab7主要多了sync文件夹,也就是sem.c , monitor.c , wait.c 等文件,增添了信号量等操作从而使得操作系统支持进程同步。在trap.c中,当发生时钟中断时,需要调用run_time_list函数。在lab6中,互斥通过lock实现,在lab7中则使用信号量实现互斥,此外增加了等待队列、计时器、禁用中断等。之后将具体分析。

1.请在实验报告中给出内核级信号量的设计描述,并说其大致执行流流程。

信号量的核心用以下的简短代码可以大致表示:

struct semaphore {
   
 int count;
 queueType queue;
 };
 void semWait(semaphore s)
 {
   
 s.count--;
 if (s.count < 0) {
   
 /* place this process in s.queue */;
 /* block this process */;
 }
 }
 void semSignal(semaphore s)
 {
   
 s.count++;
 if (s.count<= 0) {
   
/* remove a process P from s.queue */;
 /* place process P on ready list */;
}
}

当多个 (>1)进程可以进行互斥或同步合作时,一个进程会由于无法满足信号量设置的某条件而在某一位置停止,直到它接收到一个特定的信号(表明条件满足了)。为了发信号,需要使用一个称作信号量的特殊变量。为通过信号量s传送信号,信号量的V操作采用进程可执行原语semSignal(s); 为通过信号量s接收信号, 信号量的P操作采用进程可执行原语semWait(s); 如果相应的信号仍然没有发送,则进程被阻塞或睡眠,直到发送完为止 。

我将以具体的代码来分析ucore是如何实现内核信号量的。

首先定义了一些数据结构,包括信号量、等待队列等

// 定义信号量的数据结构
typedef struct {
   
    int value;                    //信号量的当前值
    wait_queue_t wait_queue;     //信号量对应的等待队列
} semaphore_t;

// 用于等待队列,存放了当前等待的线程的PCB 和 唤醒原因 和 等待队列 和 用于还原结构体的等待队列标志
typedef  struct {
   
    struct proc_struct *proc;     //等待进程的指针
    uint32_t wakeup_flags;        //进程被放入等待队列的原因标记
    wait_queue_t *wait_queue;     //指向此wait结构所属于的wait_queue
    list_entry_t wait_link;       //用来组织wait_queue中wait节点的连接
} wait_t;

信号量的计数器value 含义如下:

  • value>0, 表示共享资源的空闲数
  • vlaue<0, 表示该信号量的等待队列里的进程数
  • value=0, 表示等待队列为空

之后有相应的有关信号量的操作函数:

初始化函数 sem_init:

// 对信号量进行初始化的函数
void sem_init(semaphore_t *sem, int value) 
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值