Nachos系统调用实习报告
- 格式:docx
- 大小:1.01 MB
- 文档页数:19
实验二一.实验目的将nachos 中的lock 和condition 类的实现补充完整,并利用这些同步机制实现两个基础功能。
二.实验内容1) 实现syncy.h 中的Lock 和Condition 类,并利用这些同步机制将实验一中所双向有序链表类修改成可以在多线程线程环境下运行。
2) 实现一个线程安全的Table 。
Table 有一个固定大的Entery 数组。
3) 实现一个大小受限的BoundBuffer ,可以完成读.写功能,其中读写的size 可以超过设定的buffer 大小,当读的东西太快或写的太慢时,就将其挂起。
当buffer 里重新有写的空间或读的空间时在将其线程放入就绪队列中。
三.实验结果1.锁机制的实现 **因为lock 和condition 都有两个版本,所以当调用取得锁和释放锁的函数时我 用的是GetLock()和ReleaseLock(),而不是lock->Acquire(),Condition 同理用的是Signal ()和Wait ()。
这些函数会根据运行程序时输入的参数来决 定用哪个版本的锁或者不用锁。
a)主要代码分析 Lock 类的主要成员{public : void Acquire(); // 得到锁 void Release(); // 解放锁private: Thread *LockedThread ; // 用于储存现在拥有 lock 的线程 LockStatus status ; // 表示此时lock 的状态(Busy ,Free ) List *queue // 用于保存挂起的 线程}Lock 类中Acquire 函数得到锁,如果此时别的线程拥有锁,则此时线程被 挂起放在queue 队列中,直到有人释放锁时,Release 函数将queue 中的一 个线程加入就绪队列,每次只能由一个线程得到锁。
Condition 类主要成员{ public: void Wait(LockO *conditionLock); void Signal(LockO *conditionLock); private:List *queue ; char* name;}Condition 类的所有操作都在线程得到锁时进行操作,且运行其函数时,都 先检测 lock 是否被currentThread 锁拥有。
一题目project1:实现nachos操作系统的project1中的join()方法,condition2 类,Alarm类,Communicator类,PriorityScheduler类和Boat类project2:实现nachos操作系统的project2中的creat open read write close unlink 文件系统调用,修改UserProcess.readVirtualMemory和UserProcess.writeVirtualMemory使操作系统能够运行多用户程序,实现exec join exit系统调用,实现LotteryScheduler类二实验目的熟悉nachos操作系统,深入理解操作系统内核了解用户程序的加载过程以及多用户进程的内存分配机制三实验要求完成nachos,提交设计文档和你的代码四实验说明,程序代码及测试结果Project1:1 join()要求实现join()方法,注意,其他线程没必要调用join函数,但是如果它被调用的话,也只能被调用一次。
join()方法第二次调用的结果是不被定义的,即使第二次调用的线程和第一次调用的线程是不同的。
无论有没有被join,一个进程都能够正常结束(a)设计思想当线程B执行A.join()时,将B放入A的等待队列,直到A完成时,唤醒在等待队列中的所有线程,因此需要实现join()方法和修改finish方法(b)源代码public void join(){Lib.debug(dbgThread, "Joining to thread:" + toString());Lib.assertTrue(this!=currentThread);Lib.assertTrue(join_counter == 0);join_counter++;boolean status=Machine.interrupt().disable();if (this.status != statusFinished) {waitQueue.waitForAccess(KThread.currentThread());currentThread.sleep();}Machine.interrupt().restore(s tatus);}public static void finish(){Lib.debug(dbgThread, "Finishing thread:" +currentThread.toString());Machine.interrupt().disable();Machine.autoGrader().finishingCurrentThread();Lib.assertTrue(toBeDestroyed == null);toBeDestroyed= currentThread;currentThread.status = statusFinished;KThread thread= currentThread().waitQueue.nextThread();if (thread!= null){thread.ready();}sleep();}(c)程序截图线程1每次执行打出执行的次数,每次执行过后放弃cpu,线程2 打出successful,线程2 执行thread1.join().通过截图可以看出代码正确2 Condition2通过使用开关中断提供原子性来直接实现条件变量,我们利用信号量提供了一个简单的实现方式,你的工作就是不直接使用信号量提供相同的实现(你或许使用锁,即使它们也间接的使用了信号量)。
文件系统实习报告目录内容一:总体概述......................................... 错误!未定义书签。
内容二:任务完成情况..................................... 错误!未定义书签。
任务完成列表(Y/N).................................. 错误!未定义书签。
具体Exercise的完成情况.............................. 错误!未定义书签。
内容三:遇到的困难以及解决方法........................... 错误!未定义书签。
内容四:收获及感想....................................... 错误!未定义书签。
内容五:对课程的意见和建议............................... 错误!未定义书签。
内容六:参考文献......................................... 错误!未定义书签。
内容一:总体概述本次实习的主要内容是在nachos文件系统的基础上进行相关的优化。
目前,nachos的文件系统不甚完善,比如说文件属性的缺失,文件长度的限制,目录结构的缺失(只有根目录)以及同步互斥机制的缺失。
第一部分,我们关心文件系统基础功能,我们需要了解nachos的文件系统并实现文件属性的完善,文件长度的扩展,多级目录以及文件长度的动态调整。
第二部分,我们关心文件访问的同步互斥,我们需要了解nachos磁盘工作原理并实现文件系统的同步互斥访问机制。
Challenge部分,我们关心文件系统的优化,我们需要实现文件位置的合理分布,cache机制以及pipe机制。
内容二:任务完成情况任务完成列表(Y/N)具体Exercise的完成情况一、文件系统的基本操作Exercise 1 源代码阅读阅读Nachos源代码中与文件系统相关的代码,理解Nachos文件系统的工作原理。
nachos实验报告nachos实验报告一、引言操作系统是计算机系统中的核心软件之一,它负责管理计算机的硬件资源和提供各种服务。
为了更好地理解操作系统的原理和设计,我们在课程中进行了一系列的实验,其中之一就是使用nachos操作系统进行实验。
本报告将对我们在nachos实验中的学习和体验进行总结和分享。
二、nachos简介nachos是一个教学用的操作系统,它是为了帮助学生更好地理解操作系统的原理和设计而开发的。
nachos的设计简单、模块化,易于理解和扩展。
通过使用nachos,我们可以深入了解操作系统的各个组成部分,如进程管理、内存管理、文件系统等,并通过实验来加深对这些概念的理解。
三、实验一:进程管理在第一个实验中,我们学习了进程管理的基本原理和实现。
通过使用nachos,我们可以创建和管理多个进程,并学习它们之间的通信和同步机制。
我们了解了进程的状态转换、进程调度算法以及进程间通信的方法,如共享内存和消息传递等。
通过实验,我们更深入地理解了进程管理的重要性和挑战。
四、实验二:内存管理在第二个实验中,我们学习了内存管理的原理和实现。
nachos提供了虚拟内存的支持,我们可以通过设置页表和实现页面置换算法来管理内存。
我们了解了内存分页和分段的概念,以及常见的页面置换算法,如FIFO、LRU等。
通过实验,我们深入了解了内存管理的工作原理和性能优化方法。
五、实验三:文件系统在第三个实验中,我们学习了文件系统的原理和实现。
nachos提供了一个简单的文件系统接口,我们可以通过创建、读取和写入文件来学习文件系统的操作。
我们了解了文件系统的组织结构,如目录、文件和索引节点等,并学习了文件系统的一致性和恢复机制。
通过实验,我们更好地理解了文件系统的工作原理和性能优化方法。
六、实验四:网络通信在第四个实验中,我们学习了网络通信的原理和实现。
nachos提供了一个简单的网络模拟器,我们可以创建和管理多个网络节点,并通过网络进行通信。
w .. . .. 文件系统实习报告目录容一:总体概述 (3)容二:任务完成情况 (3)任务完成列表(Y/N) (3)具体Exercise的完成情况 (3)容三:遇到的困难以及解决方法 (39)容四:收获及感想 (41)容五:对课程的意见和建议 (41)容六:参考文献 (42)容一:总体概述本次实习的主要容是在nachos文件系统的基础上进行相关的优化。
目前,nachos的文件系统不甚完善,比如说文件属性的缺失,文件长度的限制,目录结构的缺失(只有根目录)以及同步互斥机制的缺失。
第一部分,我们关心文件系统基础功能,我们需要了解nachos的文件系统并实现文件属性的完善,文件长度的扩展,多级目录以及文件长度的动态调整。
第二部分,我们关心文件访问的同步互斥,我们需要了解nachos磁盘工作原理并实现文件系统的同步互斥访问机制。
Challenge部分,我们关心文件系统的优化,我们需要实现文件位置的合理分布,cache机制以及pipe机制。
容二:任务完成情况任务完成列表(Y/N)具体Exercise的完成情况一、文件系统的基本操作Exercise 1 源代码阅读阅读Nachos源代码中与文件系统相关的代码,理解Nachos文件系统的工作原理。
code/filesys/filesys.h和code/filesys/code/filesys/filehdr.h和code/filesys/code/filesys/directory.h和code/filesys/code/filesys/openfile.h和code /filesys/code/userprog/bitmap.h和code/userprog/code/filesys/filesys.h和code/filesys/定义文件系统FileSystemNachos实现了两套文件系统,它们对外接口是完全一致的。
一套是FILESYS_STUB,建立在UNIX文件系统之上,不使用Nachos的模拟磁盘,它主要用于先行实现其他依赖于文件系统的功能,另一套是Nachos的文件系统,实现在Nachos的虚拟磁盘之上主要常量包括#define FreeMapSector 0 //管理存空间位图文件文件头扇区#define DirectorySector 1 //根目录文件文件头扇区#define FreeMapFileSize (NumSectors / BitsInByte)//管理存空间位图文件大小#define NumDirEntries 10//根目录最多包含10个目录项#define DirectoryFileSize (sizeof(DirectoryEntry) * NumDirEntries)//根目录文件大小主要变量包括OpenFile* freeMapFile; //管理存空间位图文件OpenFile* directoryFile; //根目录文件(nachos运行过程保持打开状态)主要函数包括FileSystem(bool format) //构造函数基本功能是建立文件系统,如果format标志设置,那么建立新的文件系统,基本流程是生成位图文件和根目录文件文件头,分配位图文件和根目录文件空间,向磁盘写入位图文件和根目录文件文件头,打开位图文件和根目录文件,向磁盘写入位图文件和根目录文件。
nachos实验报告join,boat(共9篇) 操作系统nachos课程设计实验报告一题目project1:实现nachos操作系统的project1中的join()方法,condition2类,Alarm类,Communicator类,PriorityScheduler类和Boat类project2:实现nachos操作系统的project2中的creat open read write close unlink 文件系统调用,修改UserProcess.readVirtualMemory 和UserProcess.writeVirtualMemory使操作系统能够运行多用户程序,实现exec join exit系统调用,实现LotteryScheduler类二实验目的熟悉nachos操作系统,深入理解操作系统内核了解用户程序的加载过程以及多用户进程的内存分配机制三实验要求完成nachos,提交设计文档和你的代码四实验说明,程序代码及测试结果Project1:1 join()要求实现join()方法,注意,其他线程没必要调用join函数,但是如果它被调用的话,也只能被调用一次。
join()方法第二次调用的结果是不被定义的,即使第二次调用的线程和第一次调用的线程是不同的。
无论有没有被join,一个进程都能够正常结束(a)设计思想当线程B执行A.join()时,将B放入A的等待队列,直到A完成时,唤醒在等待队列中的所有线程,因此需要实现join()方法和修改finish方法(b)源代码public void join() {Lib.debug(dbgThread, Joining to thread: + toString()); Lib.assertTrue(this != currentThread); Lib.assertTrue(join_counter == 0); join_counter++; boolean status = Machine.interrupt().disable(); if (this.status != statusFinished) {waitQueue.waitForAccess(KThread.currentThread());}Machine.interrupt().restore(status);}public static void finish() {Lib.debug(dbgThread, Finishing thread: +currentThread.toString());Machine.interrupt().disable();Machine.autoGrader().finishingCurrentThread();Lib.assertTrue(toBeDestroyed == null);toBeDestroyed = currentThread;currentThread.status = statusFinished;KThread thread = currentThread().waitQueue.nextThread();if (thread != null){thread.ready();}sleep();}(c)程序截图线程1每次执行打出执行的次数,每次执行过后放弃cpu,线程2打出successful,线程2执行thread1.join().通过截图可以看出代码正确2 Condition2通过使用开关中断提供原子性来直接实现条件变量,我们利用信号量提供了一个简单的实现方式,你的工作就是不直接使用信号量提供相同的实现(你或许使用锁,即使它们也间接的使用了信号量)。
系统调用实习报告善良的大姐姐2015.5.3目录一:总体概述 (3)二:任务完成情况 (3)任务完成列表(Y/N) (3)具体Exercise的完成情况 (3)三:遇到的困难以及解决方法 (19)四:收获及感想 (20)五:对课程的意见和建议 (20)六:参考文献 (20)一:总体概述自lab4我们完成了虚拟内存的实习,可以运行用户程序之后,我们就考虑加入系统调用。
即,用户程序可以通过特定的系统调用,陷入Nachos内核,从而完成特定的目标。
本次lab一共要求完成10个系统调用,包括两大部分,文件系统相关——Create,Open,Close,Read,Write;用户程序相关——Exec,Fork,Yield,Join,Exit。
需要在阅读和理解源码的基础上,知道系统调用的执行流程,进一步修增源代码,实现新增的系统调用功能。
二:任务完成情况任务完成列表(Y/N)具体Exercise的完成情况Exercise 1:源代码阅读任务:阅读与系统调用相关的源代码,理解系统调用的实现原理。
完成情况:1.Syscall.h概述:1)定义了每个系统调用对应的系统调用号2)声明了每个系统调用概述:对系统陷入进行处理。
1)从machine的2号寄存器读入系统调用号2)执行对应的操作代码(需要自己完成)3)(如果需要)将返回值写回Machine的2号寄存器3.Start.s概述:当用户程序执行一个系统调用的时候,将参数放入2号寄存器,然后跳转到执行。
以Halt为例:4. 总结当用户希望执行一条系统调用的时候:1) 在用户程序中调用 2) 当这条语句被OneInstruction 函数解析执行时,会判断出这是一条系统调用,转入start.s3) 在start.s 中找到系统调用对应的入口(可能需要自己增加),将系统调用号放入machine 的2号寄存器,并转入4) 在 中,读出2号寄存器中的系统调用号,执行对应操作5) 必要时,将返回值写回2号寄存器,并注意,将PC 前进。
系统调用实习报告善良的大姐姐2015.5.3目录一:总体概述 (3)二:任务完成情况 (3)任务完成列表(Y/N) (3)具体Exercise的完成情况 (3)三:遇到的困难以及解决方法 (18)四:收获及感想 (19)五:对课程的意见和建议 (19)六:参考文献 (19)一:总体概述自lab4我们完成了虚拟内存的实习,可以运行用户程序之后,我们就考虑加入系统调用。
即,用户程序可以通过特定的系统调用,陷入Nachos内核,从而完成特定的目标。
本次lab一共要求完成10个系统调用,包括两大部分,文件系统相关——Create,Open,Close,Read,Write;用户程序相关——Exec,Fork,Yield,Join,Exit。
需要在阅读和理解源码的基础上,知道系统调用的执行流程,进一步修增源代码,实现新增的系统调用功能。
二:任务完成情况任务完成列表(Y/N)具体Exercise的完成情况Exercise 1:源代码阅读任务:阅读与系统调用相关的源代码,理解系统调用的实现原理。
完成情况:1.Syscall.h概述:1)定义了每个系统调用对应的系统调用号2)声明了每个系统调用概述:对系统陷入进行处理。
1)从machine的2号寄存器读入系统调用号2) 执行对应的操作代码(需要自己完成) 3) (如果需要)将返回值写回Machine 的2号寄存器3. Start.s概述:当用户程序执行一个系统调用的时候,将参数放入2号寄存器,然后跳转到 执行。
以Halt 为例:4. 总结当用户希望执行一条系统调用的时候: 1) 在用户程序中调用2) 当这条语句被OneInstruction 函数解析执行时,会判断出这是一条系统调用,转入start.s3) 在start.s 中找到系统调用对应的入口(可能需要自己增加),将系统调用号放入machine 的2号寄存器,并转入4) 在 中,读出2号寄存器中的系统调用号,执行对应操作 5) 必要时,将返回值写回2号寄存器,并注意,将PC 前进。
Nachos同步机制实习报告同步机制实习报告善良的大姐姐 2021.3.30目录一:总体概述 ........................................................................... ........ 3 二:任务完成情况 ............................................................................3 任务完成列表(Y/N) ................................................................ 3 具体Exercise的完成情况 ........................................................... 3 三:遇到的困难以及解决方法 ...................................................... 12 四:收获及感想 ........................................................................... .. 12 内容五:参考文献 (13)2一:总体概述Lab3首先要求阅读Nachos系统提供的同步机制代码,即Semaphore的实现。
其次要求修改底层源代码,达到“扩展同步机制,实现同步互斥实例”的目标。
具体来说,即要求在Semaphore的基础上,实现Lock锁和Mesa管程的Condition(条件变量)。
此外,还要利用编写的同步机制,来实现互斥实例,进而证明同步机制编写的正确性。
二:任务完成情况任务完成列表(Y/N)Exercise1 Yes Exercise2 Yes Exercise3 Yes Exercise4 Yes Challenge1 Yes Challenge2 Yes 具体Exercise的完成情况Exercise1:调研任务:调研Linux中实现的同步机制调研情况:Linux的同步机制包括好几层。
系统调用实习报告善良的大姐姐目录一:总体概述自lab4我们完成了虚拟内存的实习,可以运行用户程序之后,我们就考虑加入系统调用。
即,用户程序可以通过特定的系统调用,陷入Nachos内核,从而完成特定的目标。
本次lab一共要求完成10个系统调用,包括两大部分,文件系统相关——Create,Open,Close,Read,Write;用户程序相关——Exec,Fork,Yield,Join,Exit。
需要在阅读和理解源码的基础上,知道系统调用的执行流程,进一步修增源代码,实现新增的系统调用功能。
二:任务完成情况任务完成列表(Y/N)具体Exercise的完成情况Exercise 1:源代码阅读任务:阅读与系统调用相关的源代码,理解系统调用的实现原理。
完成情况:1.概述:1)定义了每个系统调用对应的系统调用号2)声明了每个系统调用2.概述:对系统陷入进行处理。
1)从machine的2号寄存器读入系统调用号2) 执行对应的操作代码(需要自己完成)3) (如果需要)将返回值写回Machine 的2号寄存器3.概述:当用户程序执行一个系统调用的时候,将参数放入2号寄存器,然后跳转到执行。
以Halt 为例:4. 总结当用户希望执行一条系统调用的时候: 1) 在用户程序中调用2) 当这条语句被OneInstruction 函数解析执行时,会判断出这是一条系统调用,转入3) 在中找到系统调用对应的入口(可能需要自己增加),将系统调用号放入machine的2号寄存器,并转入4) 在中,读出2号寄存器中的系统调用号,执行对应操作 5) 必要时,将返回值写回2号寄存器,并注意,将PC 前进。
6) 指令回到用户程序系统调用的下一条继续执行。
系统调用完成。
为了执行一条系统调用,我们需要完成的部分:1) 自己写一个用于测试的用户程序的.c 文件,并修改test 的Makefile ,使得用户程序能够被Nachos 系统执行。
2) 因为本次lab 需要写的系统调用,在中都已经写好了,因此我们不需要修改。
同样,中,系统调用号和函数声明也都写好了。
(但如果希望自己新增系统调用,这两个文件是需要修改的,修改方式可以参照别的系统调用) 3) 补充,执行对应的系统调用操作。
将系统调用号放入2号寄存器第一步:增加需要编译的文件名称。
这两个是我新增的第二步,增加如何编译的信息。
Exercise 2: 系统调用实现任务:类比Halt的实现,完成与文件系统相关的系统调用:Create, Open,Close,Write,Read。
文件中有这些系统调用基本说明。
Exercise 3: 编写用户程序任务:编写并运行用户程序,调用练习2中所写系统调用,测试其正误。
EX2+EX3完成情况:首先,在完成了文件系统的lab之后,为了能够让userprog编译通过,需要修改的makefile,多include几个头文件以及声明extern变量。
否则,会出现:undefined reference *** 这种情况。
其次,我们需要在中,加入系统调用入口:1.void Create(char *name)概述:1)从4号寄存器读入文件名指针2)利用指针,从Machine的mainmemory(内存)中,读出文件名3)用文件名为参数,调用filesystem的create函数,创建文件(默认长度256byte)4)将PC前移:中定义)代码:(从内存中读出文件名部分)测试截图:之后在userprog文件夹下,就出现了这个文件(因为我是用UNIX的文件系统来做这次lab的)2.OpenFileId Open(char *name)概述:1)从4号寄存器读入文件名指针2)利用指针,从Machine的mainmemory(内存)中,读出文件名3)用文件名为参数,调用filesystem的open函数,打开文件,返回OpenFile指针(在Nachos系统中,OpenFile相当于是文件描述符)4)将OpenFile指针写回machine的2号寄存器(machine->WriteRegister(2,(int)openfile))5)PC前移代码:(Openfile写回部分)测试截图:(打开失败)(Open成功会配合之后的系统调用再进行测试截图)3.void Close(OpenFileId id)概述:1)从4号寄存器中读出OpenFile的指针2)调用filesystem的close方法,将openfile关闭(自己编写的close方法,其中将传入的OpenFile指针delete掉)3)PC前移代码:(从寄存器中读出Openfile指针+关闭部分)测试截图:(Close配合open系统调用测试截图)创建文件打开文件注意:打开文件返回的文件指针,和关闭文件时读取的文件指针相同。
关闭文件4.int Read(char *buffer, int size, OpenFileId id)概述:1)从4号寄存器读出来装载字符串的指针2)从5号寄存器读出需要读取的字符串长度3)从6号寄存器读出OpenFile的指针4)调用openfile的read函数,从光标位置读出一定长度的字符串,存入临时数组当中5)将读出来的内容,写回machine的mainmemory中,写入的位置就是字符串指针依次往后。
6)将openfile的read函数的返回值,写入2号寄存器当中。
代码:测试截图:(见write部分,二者配合测试。
)5.void Write(char *buffer, int size, OpenFileId id)概述:1)从4号寄存器读出来装载字符串的指针2)从5号寄存器读出需要读取的字符串长度3)从6号寄存器读出OpenFile的指针4)从machine的mainmemory中,从字符串指针位置开始,连续读出字符串长度个字符5)将读出来的内容,调用OpenFile的write方法,写入文件当中。
代码:测试截图:a)单独测试write成功写入希望写入的内容b)配合read一起测试打开文件a,读取文件a(指针相同)打开文件b,将a读取的内容写入b(指针也相同~)字符的起始位置都是一样的。
Exercise 4: 系统调用实现任务:实现如下系统调用:Exec,Fork,Yield,Join,Exit。
文件中有这些系统调用基本说明。
Exercise 5: 编写用户程序任务:编写并运行用户程序,调用练习4中所写系统调用,测试其正确性。
EX4+EX5完成情况:首先,为了能够使得Join和Exec的系统调用,能够在父子进程之间发生联系,我们需要在中加入Thread *childThread[MaxThreadSize],用于记录当前线程的子线程的thread指针。
这个数组在thread的构造函数中初始化,初始值均为NULL。
还需要加入Thread *fatherThread变量,用于记录当前线程的父线程(如果存在)。
同样在构造函数中进行初始化,初始赋值为自己。
1.SpaceId Exec(char *name))概述:1)从4号寄存器中读出名字指针,并仿照EX2中的做法,从mainmemory中获得名字。
2)新创建一个线程3)在当前线程的childThread数组中,寻找是否还有空位,如果有,赋值给新创建的线程,标明父子关系,并且将新线程的指针号写回2号寄存器。
接着,将新创建线程的fatherThread指针赋值为currentThread。
新线程这时可以调用Fork,执行一段代码。
最后,PC前移4)如果没有空位,输出错误信息,将PC前移。
5)Fork执行的代码:参照progtest中,startprocess函数,先是打开这个用户程序文件,然后新创建一个地址空间,接着初始化machine,最后让machine->run。
代码:a)Fork之后调用的函数:b)处理系统调用的代码:测试截图:(和之后的join+exit一起测)2.int Join(SpaceId id)概述:1)从4号寄存器中读出要等待的子线程的OpenFile指针2)找到自己的childThread数组中,这个OpenFile指针对应的位置3)While循环,当这个位置不为NULL时,调用currentThread->Yield(),等待子线程结束4)跳出while循环后,将子线程的结束状态写入2号寄存器,PC前移代码:测试截图:(配合Exec和Exit一起测)3.void Exit(int status)概述:1)由于lab4虚拟内存中,需要在exit系统调用中释放page和清空tlb,因此此处继续保留这两个功能。
2)判断:如果当前exit的线程不是主线程:如果当前线程有父线程,将父线程中对应的自己设置为NULL(表明自己已经要退出啦!),并且调用currentThread->Finish() 3)如果是主线程:PC前移测试截图:(配合之前的Exec和Exit)a)测试函数:Mytest函数:b)测试截图:主线程执行Exec系统调用新Fork出来的线程(设置优先级更高,于是立即抢占)切换新线程创建自己的用户空间准备在新线程的新的用户空间中运行Mytest由于时间片到了,此时切换到主线程主线程此时执行完了Exec,开始执行Join系统调用。
由于在等待的子线程还未结束,于是让位CPU新线程执行mytest中的内容:Create一个文件,然后Exit退出(EXIT中会释放物理页)新线程执行完毕了,切换到主线程。
主线程由于上次PC没前移,于是再次调用Join。
此次成功了。
主线程调用Exit退出。
4.void Fork(void (*func)())概述:1)从4号寄存器中读出要执行的用户函数的起始PC2)新创建一个线程,并参照Exec中的步骤,完成父子关系的建立3)PC前移。
4)在Fork的系统函数中,完成准备工作:将父进程的用户空间(Pagetable)拷贝到子进程中;将machine当前的PC值修改为1)中的PC值,NextPC值修改为1)中的PC值+4;将修改完成的这套寄存器值存放到新线程的寄存器当中(其中,除了两个PC值,其余的都和父进程相同!)5)Machine->Run(),就可以跳转到用户函数执行了。
注意:1)开始时刻,子进程和父进程的寄存器值,除了PC不同,别的都相同。
2)子进程和父进程使用同样的pagetable。
3)子进程和父进程共享machine的栈空间(因此子进程不必重设栈空间)代码:测试截图:5.void Yield()概述:1)PC前移2)调用currentThread->Yield()(注意,此处二者不能调换顺序,因为一旦当前线程yield了,下一次再上CPU,是不会从没执行完的系统调用处开始,而是会从PC当前对应的指令开始的。