实验4__并发与调度

合集下载

操作系统实验二并发与调度

操作系统实验二并发与调度

实验二并发与调度一、实验目的在本实验中,通过对事件和互斥体对象的了解,来加深对Windows 2000线程同步的理解。

通过分析实验程序,了解管理事件对象的API。

了解在进程中如何使用事件对象,在进程中如何使用互斥体对象,线程如何通过文件映射对象发送数据。

二、实验环境硬件环境:计算机一台,局域网环境;软件环境:Windows 2000 Professional,Visual C++ 6.0专业版或企业版。

三、实验内容和步骤第一部分:互斥体对象本程序中显示的类CCountUpDown使用了一个互斥体来保证对两个线程间单一数值的访问。

每个线程都企图获得控制权来改变该数值,然后将该数值写入输出流中。

创建者实际上创建的是互斥体对象,计数方法执行等待并释放,为的是共同使用互斥体所需的资源(因而也就是共享资源) 。

1、利用互斥体保护共享资源程序参见实验指导书分析程序的运行结果,可以看到线程(加和减线程) 的交替执行(因为Sleep() API允许Windows切换线程) 。

在每次运行之后,数值应该返回初始值(0) ,因为在每次运行之后写入线程在等待队列中变成最后一个,内核保证它在其他线程工作时不会再运行。

1)请描述运行结果(如果运行不成功,则可能的原因是什么?) :2) 根据运行输出结果,对照分析程序,可以看出程序运行的流程吗?请简单描述:_____逆向运行__________第二部分线程通过文件对象发送数据Windows 2000提供的线程间通讯类内核对象允许同一进程或跨进程的线程之间互相发送信息,包括文件、文件映射、邮件位和命名管道等,其中最常用的是文件和文件映射。

这类对象允许一个线程很容易地向同一进程或其他进程中的另一线程发送信息。

1、演示线程通过文件对象发送数据程序参见实验指导书运行结果(如果运行不成功,则可能的原因是什么?) :阅读和分析程序,请回答问题:1) 程序中启动了多少个单独的读写线程?__________100__________________________________________________________2) 使用了哪个系统API函数来创建线程例程?_________ CreateThread()________________________________3) 文件的读和写操作分别使用了哪个API函数?_______ ReadFile()______ WriteFile()_____________ 每次运行进程时,都可看到程序中的每个线程从前面的线程中读取数据并将数据增加,文件中的数值连续增加。

进程管理实验报告分析(3篇)

进程管理实验报告分析(3篇)

第1篇一、实验背景进程管理是操作系统中的一个重要组成部分,它负责管理计算机系统中所有进程的创建、调度、同步、通信和终止等操作。

为了加深对进程管理的理解,我们进行了一系列实验,以下是对实验的分析和总结。

二、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。

2. 进一步认识并发执行的实质。

3. 分析进程争用资源的现象,学习解决进程互斥的方法。

4. 了解Linux系统中进程通信的基本原理。

三、实验内容1. 使用系统调用fork()创建两个子进程,父进程和子进程分别显示不同的字符。

2. 修改程序,使每个进程循环显示一句话。

3. 使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号,实现进程的终止。

4. 分析利用软中断通信实现进程同步的机理。

四、实验结果与分析1. 实验一:父进程和子进程分别显示不同的字符在实验一中,我们使用fork()创建了一个父进程和两个子进程。

在父进程中,我们打印了字符'a',而在两个子进程中,我们分别打印了字符'b'和字符'c'。

实验结果显示,父进程和子进程的打印顺序是不确定的,这是因为进程的并发执行。

2. 实验二:每个进程循环显示一句话在实验二中,我们修改了程序,使每个进程循环显示一句话。

实验结果显示,父进程和子进程的打印顺序仍然是随机的。

这是因为并发执行的进程可能会同时占用CPU,导致打印顺序的不确定性。

3. 实验三:使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号在实验三中,我们使用signal()捕捉键盘中断信号(按c键),然后通过kill()向两个子进程发送信号,实现进程的终止。

实验结果显示,当按下c键时,两个子进程被终止,而父进程继续执行。

这表明signal()和kill()在进程控制方面具有重要作用。

4. 实验四:分析利用软中断通信实现进程同步的机理在实验四中,我们分析了利用软中断通信实现进程同步的机理。

事务调度与并发控制数据库的实施运行和维护_真题-无答案

事务调度与并发控制数据库的实施运行和维护_真题-无答案

事务调度与并发控制、数据库的实施运行和维护(总分29,考试时间90分钟)一、单项选择题1. 下述不属于数据库维护工作的是______。

A. 使用数据定义语言建立多个表、构建数据库总体框架B. 根据备份计划周期性的备份数据库C. 检测数据库的空间使用情况D. 调整数据库参数,进行性能优化2. 下列关于排他锁和共享锁的说法中错误的是______。

A. 只能有一个事务对加锁项加排他锁B. 排他锁也叫独占锁或X锁,共享锁也叫读锁或者S锁C. 当加了S锁以后,其他的事务还可以对加锁项加X锁D. 当加了S锁以后,其他的事务还可以对加锁项加S锁3. 以下选项中是参数调整中需要关注的对象的是______。

A. 内存分配B. 资源竞争C. 磁盘I/OD. 以上全部4. 关于查询优化问题,下列说法错误的是______。

A. 将频繁地向数据库发送的某条查询语句用存储过程来代替,可以提高查询效率B. 为经常出现在查询条件中的属性建立索引,可以提高查询效率C. 先执行表连接条件,后执行查询条件,有利于提高查询效率D. 将频繁访问的视图物化并进行维护,有利于提高查询效率5. 事务T0、T1和T2并发访问数据项A、B和C,下列属于冲突操作的是______。

A.T0中的readA. 和T0中的write(A)B.T0中的readB. 和T2中的readC.C.T0中的write(A)和T2中的write(C)&nbs6. 数据库实施主要包括______。

①用DDL定义数据库结构②数据装载③编写与调试应用程序④数据库试运行A. ①②③B. ①②④C. ②③④D. ①②③④7. 以下关于顺序加锁法及其缺点叙述错误的是______。

A. 该方法对数据库中事务访问的所有数据项规定一个加锁顺序B. 每个事务在执行过程中必须按顺序对所需数据项加锁C. 维护对这些数据项的加锁顺序很困难,代价非常大D. 事务按照固定的顺序对这些数据项进行加锁比较方便8. 数据库的维护工作主要包括______。

进程的调度实验报告(3篇)

进程的调度实验报告(3篇)

第1篇一、实验目的通过本次实验,加深对操作系统进程调度原理的理解,掌握先来先服务(FCFS)、时间片轮转(RR)和动态优先级(DP)三种常见调度算法的实现,并能够分析这些算法的优缺点,提高程序设计能力。

二、实验环境- 编程语言:C语言- 操作系统:Linux- 编译器:GCC三、实验内容本实验主要实现以下内容:1. 定义进程控制块(PCB)结构体,包含进程名、到达时间、服务时间、优先级、状态等信息。

2. 实现三种调度算法:FCFS、RR和DP。

3. 创建一个进程队列,用于存储所有进程。

4. 实现调度函数,根据所选算法选择下一个执行的进程。

5. 模拟进程执行过程,打印进程执行状态和就绪队列。

四、实验步骤1. 定义PCB结构体:```ctypedef struct PCB {char processName[10];int arrivalTime;int serviceTime;int priority;int usedTime;int state; // 0: 等待,1: 运行,2: 完成} PCB;```2. 创建进程队列:```cPCB processes[MAX_PROCESSES]; // 假设最多有MAX_PROCESSES个进程int processCount = 0; // 实际进程数量```3. 实现三种调度算法:(1)FCFS调度算法:```cvoid fcfsScheduling() {int i, j;for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;if (processes[i].usedTime == processes[i].serviceTime) { processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); }for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(2)RR调度算法:```cvoid rrScheduling() {int i, j, quantum = 1; // 时间片for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;processes[i].serviceTime--;if (processes[i].serviceTime <= 0) {processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); } else {processes[i].arrivalTime++;}for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(3)DP调度算法:```cvoid dpScheduling() {int i, j, minPriority = MAX_PRIORITY;int minIndex = -1;for (i = 0; i < processCount; i++) {if (processes[i].arrivalTime <= 0 && processes[i].priority < minPriority) {minPriority = processes[i].priority;minIndex = i;}}if (minIndex != -1) {processes[minIndex].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[minIndex].processName);processes[minIndex].usedTime++;processes[minIndex].priority--;processes[minIndex].serviceTime--;if (processes[minIndex].serviceTime <= 0) {processes[minIndex].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[minIndex].processName); }}}```4. 模拟进程执行过程:```cvoid simulateProcess() {printf("请选择调度算法(1:FCFS,2:RR,3:DP):");int choice;scanf("%d", &choice);switch (choice) {case 1:fcfsScheduling();break;case 2:rrScheduling();break;case 3:dpScheduling();break;default:printf("无效的调度算法选择。

进程并发实验报告

进程并发实验报告

一、实验背景与目的随着计算机技术的发展,多任务处理和多进程并发已经成为操作系统设计中的基本要求。

为了更好地理解进程并发的基本原理和实现方法,我们进行了本次实验。

实验的目的是通过实践操作,加深对进程并发执行的理解,掌握进程创建、同步、互斥等基本概念,并学会使用相关系统调用实现进程的并发控制。

二、实验环境与工具实验环境:Windows 10操作系统,Visual Studio 2019开发环境。

实验工具:C++编程语言,WinAPI系统调用。

三、实验内容与步骤本次实验主要分为以下几个部分:1. 进程创建与并发执行- 使用CreateProcess函数创建多个进程,并观察它们的并发执行情况。

- 使用GetTickCount函数获取每个进程的执行时间,分析并发执行的效果。

2. 进程同步- 使用互斥锁(mutex)实现进程间的同步,确保同一时刻只有一个进程访问共享资源。

- 使用条件变量(condition variable)实现进程间的条件同步,实现生产者-消费者模型。

3. 进程互斥- 使用信号量(semaphore)实现进程间的互斥,避免资源竞争。

- 使用临界区(critical section)保护共享资源,防止多个进程同时访问。

4. 实验分析- 分析实验结果,总结进程并发、同步和互斥的原理和方法。

- 讨论实验中遇到的问题和解决方法。

四、实验代码示例以下是一个简单的实验代码示例,演示了使用互斥锁实现进程同步的过程:```cpp#include <windows.h>#include <iostream>using namespace std;// 全局互斥锁mutex mtx;void processFunction(){unique_lock<mutex> lock(mtx);cout << "Process " << GetCurrentProcessId() << " is running." << endl;lock.unlock();}int main(){// 创建两个进程CreateProcess(NULL, "process.exe", NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);// 主进程继续执行cout << "Main process is running." << endl;return 0;}```五、实验结果与分析1. 进程创建与并发执行通过实验,我们观察到多个进程可以并发执行,并且每个进程的执行时间都会有所不同。

设计一个若干并发进程的进程调度程序

设计一个若干并发进程的进程调度程序

操作系统实验报告指导:琚耀操作系统实验题1:设计一个若干并发进程的进程调度程序一、实验目的二、实验要求用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解.三、实验内容进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。

每个进程有一个进程控制块( PCB)表示。

进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。

进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。

进程的到达时间是程输入的时间。

进程的运行时间以时间片为单位进行计算。

每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

就绪进程获得 CPU后都只能运行一个时间片。

用已占用CPU时间加1来表示。

如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。

每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查重复以上过程,直到所要进程都完成为止。

四、实验算法流程:调度算法的流程图如下 :2011 信管专业C:\iknow\docshare\data\cur_work\199703291.doc 日期:2013 -11-25五、实验程序清单:(参考某资料)#include "stdio.h"#include <stdlib.h>#include <conio.h>#define getpch(type) (type*)malloc(sizeof(type))#define NULL 0struct pcb { /* 定义进程控制块PCB */char name[10];char state; 状态int super; 优先级int ntime; 运行时间int rtime; 已运行时间struct pcb* link;}*ready=NULL,*p;typedef struct pcb PCB;char sort() /* 建立对进程进行优先级排列函数*/{ PCB *first, *second;int insert=0;if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/ { p->link=ready;ready=p;}else /* 进程比较优先级,插入适当的位置中*/{ first=ready;second=first->link;while(second!=NULL){ if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/ { /*插入到当前进程前面*/p->link=second;first->link=p;second=NULL;insert=1;}else /* 插入进程优先数最低,则插入到队尾*/{ first=first->link;second=second->link;}}if(insert==0) first->link=p;}}char input() /* 建立进程控制块函数*/{ int i,num;//clrscr(); /*清屏*/printf("\n 请输入被调度的进程数目:");scanf("%d",&num);for(i=0;i<num;i++){ printf("\n 进程号No.%d:\n",i);p=getpch(PCB);printf("\n 输入进程名:");scanf("%s",p->name);printf("\n 输入进程优先数:");scanf("%d",&p->super);printf("\n 输入进程运行时间:");scanf("%d",&p->ntime);printf("\n");p->rtime=0;p->state='w';p->link=NULL;sort(); /* 调用sort函数*/ } }int space(){ int l=0; PCB* pr=ready;while(pr!=NULL){ l++;pr=pr->link; }return(l); }char disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/{ printf("\n qname \t state \t super \t ndtime \t runtime \n"); printf("|%s\t",pr->name);printf("|%c\t",pr->state);printf("|%d\t",pr->super);printf("|%d\t",pr->ntime);printf("|%d\t",pr->rtime);printf("\n");}char check() /* 建立进程查看函数 */{ PCB* pr;printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/ disp(p);pr=ready;printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/while(pr!=NULL){ disp(pr);pr=pr->link;}}char destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/{ printf("\n 进程 [%s] 已完成.\n",p->name);free(p);}char running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/ { (p->rtime)++;if(p->rtime==p->ntime)destroy(); /* 调用destroy函数*/else{(p->super)--;p->state='w';sort(); /*调用sort函数*/ }}main() /*主函数*/{ int len,h=0;char ch;input();len=space();while((len!=0)&&(ready!=NULL)){ ch=getchar();h++;printf("\n The execute number:%d \n",h); p=ready;ready=p->link;p->link=NULL;p->state='R';check();running();printf("\n 按任一键继续......");ch=getchar();}printf("\n\n 进程已经完成.\n");ch=getchar();}六、运行结果分析结果分析:根据上述输入的三个进程的信息可以得到:优先级最高的是进程mhy,所以最先调度进程mhy,它的状态为运行态,需要执行的时间为2。

综合设计多进程并发与调度仿真环境

综合设计多进程并发与调度仿真环境

综合设计多进程并发与调度仿真环境一、课程设计目的进行操作系统课程设计主要是在学习操作系统课程的基础上,在完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。

同时,可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力、创新能力及团队组织、协作开发软件的能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。

二、课程设计内容综合设计多进程并发与调度仿真环境,分析比较各种调度算法的性能。

三、系统分析与设计1、系统分析:在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。

当就绪状态进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。

本实验就这一问题给出了四种调度算法。

分别为先来先服务、短作业优先、高优先权调度和时间片轮转算法。

2、系统设计:(1)设计一个生成有几个互斥的待处理进程的主界面。

(2)再设计一个按钮可实现随机重新生成这几个进程的各种属性(这里用到了随机函数)(3)再分别设置四个按钮分别用四个算法对上诉诸进程进行调度。

(4)对于上诉四个算法再分别为每种算法相应对应的对话框,用来加以区别和独立。

3、模块设计:4、数据结构说明:struct Process{CString Name ;int ArriveTime;int NeedTime ;int RealTime ;int FinishTime;int Level ;CString State ;};struct Queue{CString Name ;int ArriveTime;int NeedTime ;int Level ;CString State ;};5、算法流程图:处理器调度算法流图如下:四、模块调试与系统测试1、模块调试:输入的形式和输入值的范围输出的形式程序所能达到的功能2、系统测试:测试方法:由于软件错误的复杂性,软件测试需要综合应用测试技术,软件测试步骤为单元测试、集成测试、确认测试和系统测试。

(完整word版)操作系统作业调度实验报告-多道批处理

(完整word版)操作系统作业调度实验报告-多道批处理

计算机学院计算机科学与技术专业07 班姓名学号教师评定_________________实验题目作业调度一、实验目的本实验要求学生模拟作业调度的实现,用高级语言编写和调试一个或多个作业调度的模拟程序,了解作业调度在操作系统中的作用,以加深对作业调度算法的理解。

二、实验内容和要求1、为单道批处理系统设计一个作业调度程序(1)、编写并调试一个单道处理系统的作业调度模拟程序。

(2)、作业调度算法:分别采用先来先服务(FCFS),最短作业优先(SJF)的调度算法。

(3)、由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的CPU时限等因素。

(4)、每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、所需的资源、作业状态、链指针等等。

作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。

每个作业的最初状态总是等待W。

(5)、对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,并比较各种算法的优缺点。

2、模拟批处理多道操作系统的作业调度(1)写并调试一个作业调度模拟程序。

(2)作业调度算法:分别采用先来服务(FCFS)调度算法。

(3)在批处理系统中,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求,所需要的资源是否得到满足。

作业调度程序负责从输入井选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理机运行。

作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。

但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业要求,那么,作业调度必须按一定的算法在这些作业中作出选择。

操作系统实验4-Linux 进程管理

操作系统实验4-Linux 进程管理

实验四Linux进程管理实验—、实验目的1 .在本实验中学习Linux操作系统的进程状态,并通过编写一些简单代码来观察各种情况下,Linux进程的状态, 进一步理解进程的状态及其转换机制。

2.通过本实验学习如何创建Linux进程及线程,通过实验,观察Linux进程及线程的异步执行。

理解进程及线程的区别及特性,进一步理解进程是资源分配单位,线程是独立调度单位。

二、实验环境硬件环境:计算机一台,局域网环境;软件环境:Linux Ubuntu操作系统,gcc编译器。

三、实验内容和步骤1、Linux进程状态及其相互转换Linux系统中的进程主要有以下六种状态。

(1)TASK_RUNNING (可运行状态)。

正在运行的进程或在可运行进程队列(run_queue)中等待运行的进程处于该状态。

它实际上包含一般操作系统原理教材中所谓进程三种基本状态中的运行态和就绪两种状态。

当CPU空闲时,进程调度程序只在处于该状态的进程中选择优先级最高的进程运行。

Linux中运行态的进程可以进一步细分为3种:内核运行态、用户运行态和就绪态。

(2)TASKJNTERRUPTIBLE (可中断阻塞状态)。

处于可中断阻塞状态的进程排成一个可中断阻塞状态进程队列, 该队列中的阻塞进程在资源有效时,能被信号或中断唤醒进入到运行态队列。

(3)TASK.UNINTERRUPTIBLE (不可中断阻塞状态)。

不可中断指的是进程不响应信号。

处于不可中断阻塞状态的进程排成一个不可中断阻塞状态进程队列。

该队列中的阻塞进程,不可被其他进程唤醒,只有被使用wake_up() 函数明确唤醒时才能转换到可运行的就绪状态。

(4)TASK_STOP/TASK_TRACED (暂停状态)。

当进程收到信号 SIGSTOP、SIGTSTP. SIGTTIN 或 SIGTTOU 时就会进入暂停状态。

可向其发送SIGCONT信号,让进程转换到可运行状态。

(5)TASK_DEAD-EXIT_ZOMBIE (僵死状态)。

计算机系统结构实验-循环展开和指令调度.

计算机系统结构实验-循环展开和指令调度.

中央民族大学实验报告
八、实验数据及结果分析:
一、用指令调度技术解决流水线中的结构相关与数据相关:
1、instruction.s文件的代码:
2、运行程序部分截图
3、未用指令调度技术之前程序执行过程中的相关:
4、运行结果数据统计
5、采用指令调度后的程序代码
6、采用调度技术后发生的关联
7、运行结果数据统计
二、用循环展开、寄存器换名以及指令调度提高性能:
1、test.s文件的源代码如下:
2、运行test.s文件,记录运行过程中存在的相关,以及运行总的时钟周期数
3、将循环展开3次,将4个循环体组成的代码代替原来的循环体,并对程序做相应的修改。

然后对新的循环体进行寄存器换名和指令调度,代码如下:
4、记录执行过程中各种相关发生的次数以及程序执行的总时钟周期数:。

windows操作系统实验报告

windows操作系统实验报告

大学操作系统实验报告实验一进程控制与描述一、实验目的通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。

通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows2000进程的“一生”。

三、实验内容和步骤第一部分:Windows2000Professional下的GUI应用程序,使用V isualC++编译器创建一个GUI应用程序,代码中包括了WinMain()方法,该方法GUI类型的应用程序的标准入口点。

程序1-1Windows2000的GUI应用程序也可以利用任何其他文本编辑器键入程序代码,如果这样,例如使用WORD来键入和编辑程序,则应该注意什么问题?保存时,将文件保存为扩展名为*.cpp的C++源文件。

在程序1-1的GUI应用程序中,首先需要Windows.h头文件,以便获得传送给WinMain()和MessageBox()API 函数的数据类型定义。

接着的pragma指令指示编译器/连接器找到User32.LIB库文件并将其与产生的EXE文件连接起来。

这样就可以运行简单的命令行命令CLMsgBox.CPP来创建这一应用程序,如果没有pragma指令,则MessageBox()API 函数就成为未定义的了。

这一指令是V isualStudioC++编译器特有的。

接下来是WinMain()方法。

其中有四个由实际的低级入口点传递来的参数。

hInstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandle()API函数将这些资源提取出来。

系统利用实例句柄来指明代码和初始的数据装在内存的何处。

句柄的数值实际上是EXE文件映像的基地址,通常为0x00400000。

下一个参数hPrevInstance是为向后兼容而设的,现在系统将其设为NULL。

应用程序的命令行(不包括程序的名称)是lpCmdLine参数。

进程调度实验报告

进程调度实验报告

操作系统实验 报告实验项目: 进程调度学 院: 计算机学院专 业:班 级:学 号:姓 名:1. 实验目的在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。

当就绪进程个数大于处理机数时,就必须依照某种策略来决定哪些进程优先占用处理机。

本实验模拟在单处理机情况下的进程调度,加深了解进程调度的工作。

2. 实验内容设计一个按时间片轮转法实现进程调度的程序。

(1)假定系统有五个进程,每一个进程用一个进程控制块PCB 来代表,进程控制块的格式为:其中,进程名——作为进程的标识,假设五个进程的进程名分别为Q 1,Q 2,Q 3,Q 4,Q 5。

指针——进程按顺序排成循环队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程的指针指出第一个进程的进程控制块首地址。

要求运行时间——假设进程需要运行的单位时间数。

已运行时间——假设进程已经运行的单位时间数,初始值为“0”。

状态——有两种状态,“就绪”和“结束”,初始状态都为“就绪”,用“R ”表示。

当一个进程运行结束后,它的状态为“结束”,用“E ”表示。

(2)每次运行所设计的进程调度程序前,为每个进程任意确定它的“要求运行时间”。

(3)把五个进程按顺序排成循环队列,用指针指出队列连接情况。

另用一标志单元记录轮到运行的进程。

例如,当前轮到Q 2执行,则有:进程名 指针 要求运行时间 已运行时间 状态标志单元(4)进程调度总是选择标志单元指示的进程运行。

由于本实验是模拟进程调度的功能,所以对被选中的进程并不实际的启动运行,而是执行“已运行时间+1”来模拟进程的一次运行,表示进程已经运行过一个单位的时间。

请注意:在实际的系统中,当一个进程被选中运行时,必须置上该进程可以运行的时间片值,以及恢复进程的现场,让它占有处理机运行,直到出现等待事件或运行满一个时间片。

在这时省去了这些工作,仅用“已运行时间+1”来表示进程已经运行满一个时间片。

(5)进程运行一次后,应把该进程的进程控制块中的指针值送到标志单元,以指示下一个轮到运行的进程。

操作系统实验四 磁盘调度算法

操作系统实验四 磁盘调度算法

实验四磁盘调度一、实验目的:本实验要求学生模拟设计一个磁盘调度程序,观察调度程序的动态运行过程。

通过实验让学生理解和掌握磁盘调度的职能。

二、实验内容:对磁盘进行移臂操作,模拟磁盘调度算法并计算平均寻道时间三、实验准备:1.相关理论知识:(1)假设磁盘只有一个盘面,并且磁盘是可移动头磁盘。

(3)磁盘是高速、大容量、旋转型、可直接存取的存储设备。

它作为计算机系统的辅助存储器,担负着繁重的输入输出工作,在现代计算机系统中往往同时会有若干个要求访问磁盘的输入输出要求。

系统可采用一种策略,尽可能按最佳次序执行访问磁盘的请求。

由于磁盘访问时间主要受寻道时间T的影响,为此需要采用合适的寻道算法,以降低寻道时间。

(2)磁盘是可供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。

当有进程在访问某个磁盘时,其它想访问该磁盘的进程必须等待,直到磁盘一次工作结束。

当有多个进程提出输入输出请求而处于等待状态时,可用磁盘调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。

2.测试数据:磁盘读写请求队列:20,44,40,4,80,12,76当前磁头位置:50试问采用FCFS、SSTF、SCAN磁盘调度算法时寻道顺序及平均寻道时间分别为多少?四、实验过程:1.流程图SCAN算法(扫描算法)流程图:2. 源代码#include<stdio.h>#include<stdlib.h>#include<iostream.h>#include<math.h>#define maxsize 1000/*********************判断输入数据是否有效**************************/int decide(char str[]) //判断输入数据是否有效{int i=0;while(str[i]!='\0'){if(str[i]<'0'||str[i]>'9'){return 0;break;}i++;}return i;}/******************将字符串转换成数字***********************/ int trans(char str[],int a) //将字符串转换成数字{int i;int sum=0;for(i=0;i<a;i++){sum=sum+(int)((str[i]-'0')*pow(10,a-i-1));}return sum;}/*********************冒泡排序算法**************************/ int *bubble(int cidao[],int m){int i,j;int temp;for(i=0;i<m;i++) //使用冒泡法按从小到大顺序排列for(j=i+1;j<m;j++){if(cidao[i]>cidao[j]){temp=cidao[i];cidao[i]=cidao[j];cidao[j]=temp;}}cout<<"排序后的磁盘序列为:";for( i=0;i<m;i++) //输出排序结果{cout<<cidao[i]<<" ";}cout<<endl;return cidao;}/*********************先来先服务调度算法************************/ void FCFS(int cidao[],int m) //磁道号数组,个数为m{int now;//当前磁道号int sum=0; //总寻道长度int j,i;int a;char str[100];float ave; //平均寻道长度cout<<"磁盘请求序列为:";for( i=0;i<m;i++) //按先来先服务的策略输出磁盘请求序列{cout<<cidao[i]<<" ";}cout<<endl;cout<<"请输入当前的磁道号:";B: cin>>str; //对输入数据进行有效性判断a=decide(str);if(a==0){cout<<"输入数据的类型错误,请重新输入!"<<endl;goto B;}elsenow=trans(str,a); //输入当前磁道号sum+=abs(cidao[0]-now);cout<<"磁盘扫描序列为:";for( i=0;i<m;i++) //输出磁盘扫描序列{cout<<cidao[i]<<" ";}for(i=0,j=1;j<m;i++,j++) //求平均寻道长度{sum+=abs(cidao[j]-cidao[i]);ave=(float)(sum)/(float)(m);}cout<<endl;cout<<"平均寻道长度:"<<ave<<endl;}/**********************最短寻道时间优先调度算法********************/void SSTF(int cidao[],int m){int k=1;int now,l,r;int i,j,sum=0;int a;char str[100];float ave;cidao=bubble(cidao,m); //调用冒泡排序算法排序cout<<"请输入当前的磁道号:";C: cin>>str; //对输入数据进行有效性判断a=decide(str);if(a==0){cout<<"输入数据的类型错误,请重新输入!"<<endl;goto C;}elsenow=trans(str,a); //输入当前磁道号if(cidao[m-1]<=now) //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务{cout<<"磁盘扫描序列为:";for(i=m-1;i>=0;i--)cout<<cidao[i]<<" ";sum=now-cidao[0];}if(cidao[0]>=now) //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务{cout<<"磁盘扫描序列为:";for(i=0;i<m;i++)cout<<cidao[i]<<" ";sum=cidao[m-1]-now;}if(now>cidao[0]&&now<cidao[m-1]) //若当前磁道号大于请求序列中最小者且小于最大者{cout<<"磁盘扫描序列为:";while(cidao[k]<now) //确定当前磁道在已排的序列中的位置,后面的算法都用到了,可以直接复制后少量修改,节省时间。

并发与调度

并发与调度

并发与调度一、实验目的在本实验中,通过对事件和互斥体对象的了解,来加深对Windows 2000线程同步的理解。

通过分析实验程序,了解管理事件对象的API。

了解在进程中如何使用事件对象,在进程中如何使用互斥体对象,线程如何通过文件映射对象发送数据。

二、实验环境硬件环境:计算机一台,局域网环境;软件环境:Windows 2000 Professional,Visual C++ 6.0专业版或企业版。

三、实验内容和步骤第一部分:互斥体对象本程序中显示的类CCountUpDown使用了一个互斥体来保证对两个线程间单一数值的访问。

每个线程都企图获得控制权来改变该数值,然后将该数值写入输出流中。

创建者实际上创建的是互斥体对象,计数方法执行等待并释放,为的是共同使用互斥体所需的资源(因而也就是共享资源) 。

1、利用互斥体保护共享资源// mutex项目# include <windows.h># include <iostream>// 利用互斥体来保护同时访问的共享资源classCCountUpDown{public:// 创建者创建两个线程来访问共享值CCountUpDown(intnAccesses) :m_hThreadlnc(INV ALID_HANDLE_V ALUE) ,m_hThreadDec(INV ALID_HANDLE_V ALUE) ,m_hMutexValue(INV ALID_HANDLE_V ALUE) ,m_nValue(0) ,m_nAccess(nAccesses){// 创建互斥体用于访问数值m_hMutexValue= :: CreateMutex(NULL, // 缺省的安全性TRUE, // 初始时拥有,在所有的初始化结束时将释放NULL) ; // 匿名的m_hThreadInc= :: CreateThread(NULL, // 缺省的安全性0, // 缺省堆栈IncThreadProc,// 类线程进程reinterpret_cast<LPVOID> (this) , // 线程参数0, // 无特殊的标志NULL) ; // 忽略返回的idm_hThreadDec= :: CreateThread(NULL, // 缺省的安全性0, // 缺省堆栈DecThreadProc, // 类线程进程reinterpret_cast<LPVOID> (this) , // 线程参数0, // 无特殊的标志NULL) ; // 忽略返回的id// 允许另一线程获得互斥体:: ReleaseMutex(m_hMutexValue) ;}// 解除程序释放对对象的引用virtual ~CCountUpDown(){:: CloseHandle(m_hThreadInc) ;:: CloseHandle(m_hThreadDec) ;:: CloseHandle(m_hMutexValue) ;}// 简单的等待方法,在两个线程终止之前可暂停主调者virtual void WaitForCompletion(){// 确保所有对象都已准备好if (m_hThreadInc != INVALID_HANDLE_V ALUE &&m_hThreadDec != INV ALID_HANDLE_V ALUE){// 等待两者完成(顺序并不重要):: WaitForSingleObject(m_hThreadInc, INFINITE) ;:: WaitForSingleObject(m_hThreadDec, INFINITE) ;}}protected:// 改变共享资源的简单的方法virtual void DoCount(intnStep){// 循环,直到所有的访问都结束为止while (m_nAccess> 0){// 等待访问数值:: WaitForSingleObject(m_hMutexValue, INFINITE) ;// 改变并显示该值m_nValue += nStep;std :: cout<< “thread: ” << :: GetCurrentThreadId()<< “value: ”<<m_nvalue<< “access: ”<<m_nAccess<<std :: endl;// 发出访问信号并允许线程切换--m_nAccess;:: sleep(l000) ; // 使显示速度放慢// 释放对数值的访问:: ReleaseMutex(m_hMutexValue) ;}}static DWORD WINAPI IncThreadProc(LPVOID lpParam){// 将参数解释为‟this‟指针CCountUpDown* pThis =reinterpret_cast<CCountUpDown* > (lpParam) ;// 调用对象的增加方法并返回一个值pThis ->DoCount(+1) ;return(0) ;}static DWORD WINAPI DecThreadProc(LPVOID lpParam){// 将参数解释为…this‟ 指针CCountUpDown* pThis =reinterpret_cast<CCountUpDown* > (lpParam) ;// 调用对象的减少方法并返回一个值pThis ->DOCount(-1) ;return(0) ;}protected:HANDLE m_hThreadInc;HANDLE m_hThreadDec;HANDLE m_hMutexValue;intm_nValue;intm_nAccess ;} ;void main(){CCountUpDownud(50) ;ud.WaitForCompletion() ;}# include <windows.h># include <iostream>// 利用互斥体来保护同时访问的共享资源class CCountUpDown{public:// 创建者创建两个线程来访问共享值CCountUpDown(int nAccesses) :m_hThreadInc(INV ALID_HANDLE_V ALUE) ,m_hThreadDec(INV ALID_HANDLE_V ALUE) ,m_hMutexValue(INV ALID_HANDLE_VALUE) ,m_nValue(0) ,m_nAccess(nAccesses){// 创建互斥体用于访问数值m_hMutexValue= :: CreateMutex(NULL, // 缺省的安全性TRUE, // 初始时拥有,在所有的初始化结束时将释放NULL) ; // 匿名的m_hThreadInc= :: CreateThread(NULL, // 缺省的安全性0, // 缺省堆栈IncThreadProc, // 类线程进程reinterpret_cast<LPVOID> (this) , // 线程参数0, // 无特殊的标志NULL) ; // 忽略返回的idm_hThreadDec= :: CreateThread(NULL, // 缺省的安全性0, // 缺省堆栈DecThreadProc, // 类线程进程reinterpret_cast<LPVOID> (this) , // 线程参数0, // 无特殊的标志NULL) ; // 忽略返回的id// 允许另一线程获得互斥体:: ReleaseMutex(m_hMutexValue) ;}// 解除程序释放对对象的引用virtual ~CCountUpDown(){:: CloseHandle(m_hThreadInc) ;:: CloseHandle(m_hThreadDec) ;:: CloseHandle(m_hMutexValue) ;}// 简单的等待方法,在两个线程终止之前可暂停主调者virtual void WaitForCompletion(){// 确保所有对象都已准备好if (m_hThreadInc != INV ALID_HANDLE_VALUE &&m_hThreadDec != INV ALID_HANDLE_V ALUE){// 等待两者完成(顺序并不重要):: WaitForSingleObject(m_hThreadInc, INFINITE) ;:: WaitForSingleObject(m_hThreadDec, INFINITE) ;}}protected:// 改变共享资源的简单的方法virtual void DoCount(int nStep){// 循环,直到所有的访问都结束为止while (m_nAccess> 0){// 等待访问数值:: WaitForSingleObject(m_hMutexValue, INFINITE) ;// 改变并显示该值m_nValue += nStep;std :: cout<< "thread: " << :: GetCurrentThreadId()<< "value: "<<m_nValue<< "access: "<<m_nAccess<<std :: endl;// 发出访问信号并允许线程切换--m_nAccess;:: Sleep(1000) ; // 使显示速度放慢// 释放对数值的访问:: ReleaseMutex(m_hMutexValue) ;}}static DWORD WINAPI IncThreadProc(LPVOID lpParam){// 将参数解释为'this'指针CCountUpDown* pThis =reinterpret_cast<CCountUpDown* > (lpParam) ;// 调用对象的增加方法并返回一个值pThis ->DoCount(+1) ;return(0) ;}static DWORD WINAPI DecThreadProc(LPVOID lpParam){// 将参数解释为'this' 指针CCountUpDown* pThis =reinterpret_cast<CCountUpDown* > (lpParam) ;// 调用对象的减少方法并返回一个值pThis ->DoCount(-1) ;return(0) ;}protected:HANDLE m_hThreadInc;HANDLE m_hThreadDec;HANDLE m_hMutexValue;int m_nValue;int m_nAccess ;} ;void main(){CCountUpDown ud(50) ;ud.WaitForCompletion() ;}分析程序的运行结果,可以看到线程 (加和减线程) 的交替执行(因为Sleep() API允许Windows切换线程) 。

实验二并发与调度

实验二并发与调度

一、实验名称实验二并发与调度二、实验目的在本实验中,通过对事件和互斥体对象的了解,来加深对Windows Server 2003线程同步的理解。

1) 回顾系统进程、线程的有关概念,加深对Windows Server 2003线程的理解。

2) 了解事件和互斥体对象。

3) 通过分析实验程序,了解管理事件对象的API。

4) 了解在进程中如何使用事件对象。

5) 了解在进程中如何使用互斥体对象。

6) 了解父进程创建子进程的程序设计方法。

三、实验内容父进程启动时,利用CreateEvent() API创建一个命名的、可共享的事件和子进程,然后等待子进程向事件发出信号并终止父进程。

在创建时,子进程通过OpenEvent() API打开事件对象,调用SetEvent() API使其转化为已接受信号状态。

两个进程在发出信号之后几乎立即终止。

四、实验步骤步骤1:登录进入Windows Server 2003 。

步骤2:在“开始”菜单中单击“程序”-“Microsoft Visual Studio 6.0”–“Microsoft Visual C++ 6.0”命令,进入Visual C++窗口。

步骤3:在工具栏单击“打开”按钮,在“打开”对话框中找到并打开实验源程序4-1.cpp。

步骤4:单击“Build”菜单中的“Compile 4-1.cpp”命令,并单击“是”按钮确认。

系统对4-1.cpp进行编译。

步骤5:编译完成后,单击“Build”菜单中的“Build 4-1.exe”命令,建立4-1.exe可执行文件。

操作能否正常进行?如果不行,则可能的原因是什么?_ 操作能正常运行。

________________步骤6:在工具栏单击“Execute Program”(执行程序) 按钮,执行4-1.exe程序。

运行结果(分行书写。

如果运行不成功,则可能的原因是什么?) :1) ___event created______________________________________________________________2) ___child created_______________________________________________________________3) ___Parent waiting on child._____________________________________________ ________4) ___child process begining……_________________________ ___________________________5) ___ event signaled______________________________________________________________6) ___ parent received the envent signaling from child_________________________________7) ___ Parent released._____________________________________________________________这个结果与你期望的一致吗?(从进程并发的角度对结果进行分析)答:这个结果与期望一致。

实验二-多进程并发环境及调度算法的仿真设计

实验二-多进程并发环境及调度算法的仿真设计

课外实验二多道进程并发环境及调度算法的仿真设计一、实验目的通过程序仿真掌握处理机执行进程、进程切换及调度算法的原理、过程与步骤;二、实验内容1、仿真设计CPU、寄存器、时钟中断等硬件部件(1)C PU抽象设计CPU可抽象为一个类或结构体。

关键寄存器可抽象为类的属性或结构体成员,至少包括:程序计数器(PC)、指令寄存器(IR)、状态寄存器(PSW)等,寄存器内容的表示方式自行设计。

CPU模式切换的现场保护、现场恢复操作可封装为方法。

(2)时钟中断抽象设计可抽象为一个整数或一个类或结构体,也可用计时器、线程等方法仿真。

读取当前机内时间、将时间转换为秒为单位的整数等操作可以封装为方法。

本实验:假设计算机1s发生一次时钟中断。

进程调度时间片长短是1s的整数倍。

本实验仿真时钟中断是为了仿真并发进程请求,模拟并发环境。

2、仿真设计进程PCB、PCB表的数据结构(1)进程控制块PCB设计参照Linux task_struct的数据结构内容设计;至少包含:进程编号(ProID),进程优先数(Priority)、进程创建时间(InTimes)、进程状态(ProState)、进程运行时间(RunTimes)、进程包含的指令数目(InstrucNum)、编号指令(Instruc_ID)、每条指令的状态标志(Instruc_State,0表示核心态、1表示用户态)、单指令运行时间(Instruc_Times)、进程当前状态(PSW)等信息。

例如:说明:★请求运行的并发进程个数可以随机产生,也可以事先设定★进程创建时间(InTimes):根据当前机内时间,在10分钟内随机生成时间递增序列。

★进程运行时间(RunTime):统计进程当前已运行了时间★进程包含的指令数目(InstrucNum)用100以内的随机数产生;★编号指令(Instruc_ID):进程编号与指令序号的合并,例如ProID=1的进程的第1条指令编号为Instruc_ID=0101★每条指令的类型标志(Instruc_State,0表示系统调用、1表示用户态操作、2表示I/O数据通信):用随机数产生0、1、2。

调度业务的实验报告

调度业务的实验报告

一、实验目的1. 理解调度业务的基本概念和原理;2. 掌握调度算法的设计与实现;3. 分析调度算法的性能指标,评估不同调度算法的优劣;4. 提高在实际业务场景中运用调度算法的能力。

二、实验内容1. 调度业务背景介绍调度业务是指根据一定的规则和优先级,对业务请求进行排序、分配资源、执行和处理的过程。

调度算法是调度业务的核心,其性能直接影响业务系统的运行效率。

2. 调度算法设计与实现(1)先来先服务(FCFS)算法FCFS算法按照业务请求到达的顺序进行调度,即先到达的业务请求先执行。

其实现如下:- 定义一个业务请求队列,用于存储所有待处理的业务请求;- 按照业务请求到达的顺序,将业务请求依次加入队列;- 从队列中取出业务请求,执行并处理;- 执行完成后,从队列中移除业务请求。

(2)最短作业优先(SJF)算法SJF算法根据业务请求的处理时间进行调度,即优先执行处理时间最短的业务请求。

其实现如下:- 定义一个业务请求队列,用于存储所有待处理的业务请求;- 将业务请求按照处理时间从小到大排序;- 从队列中取出处理时间最短的业务请求,执行并处理;- 执行完成后,从队列中移除业务请求。

(3)优先级调度算法优先级调度算法根据业务请求的优先级进行调度,即优先执行优先级高的业务请求。

其实现如下:- 定义一个业务请求队列,用于存储所有待处理的业务请求;- 将业务请求按照优先级从高到低排序;- 从队列中取出优先级最高的业务请求,执行并处理;- 执行完成后,从队列中移除业务请求。

3. 调度算法性能分析为了评估不同调度算法的性能,我们选取以下性能指标进行分析:- 平均周转时间:业务请求从到达系统到完成处理所需的时间;- 平均等待时间:业务请求在系统中的等待时间;- 系统吞吐量:单位时间内系统处理的业务请求数量。

4. 实验结果与分析通过模拟不同业务请求的到达和执行,我们得到以下实验结果:(1)FCFS算法- 平均周转时间:10.5- 平均等待时间:5.25- 系统吞吐量:0.1(2)SJF算法- 平均周转时间:8.5- 平均等待时间:4.25- 系统吞吐量:0.1(3)优先级调度算法- 平均周转时间:9- 平均等待时间:4.5- 系统吞吐量:0.1从实验结果可以看出,SJF算法在平均周转时间和平均等待时间方面表现较好,而FCFS算法和优先级调度算法在系统吞吐量方面表现较好。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

背景知识
文件对象
• 文件对象是人们所熟悉的永久存储的传统元素。将一个 文件对象是人们所熟悉的永久存储的传统元素。 文件看作是内核对象可使开发人员获得比标准C++ 文件看作是内核对象可使开发人员获得比标准C++ 文件 操作更为强大的功能 • 内核允许开发人员在系统设备或网络上创建代表永久存 储数据块的文件对象。 储数据块的文件对象。这些文件对象是对永久存储数据 的低级访问者; 的低级访问者;用C++ 运行库或其他方法打开的所有文 件最终都要变成对CreateFile() API的调用 件最终都要变成对CreateFile() API的调用 • CreateFile() 函数分配一个内核对象来代表一个永久的文 件。当在磁盘上创建一个新文件或当打开一个已经存在 的文件时,就调用这个API 的文件时,就调用这个API
背景知识
而互斥体则是另一个可命名且安全的内核对象,其 互斥体则是另一个可命名且安全的内核对象,Байду номын сангаас主要目的是引导对共享资源的访问。 主要目的是引导对共享资源的访问。拥有单一访问 资源的线程创建互斥体, 资源的线程创建互斥体,所有想要访问该资源的线 程应该在实际执行操作之前获得互斥体, 程应该在实际执行操作之前获得互斥体,而在访问 结束时立即释放互斥体, 结束时立即释放互斥体,以允许下一个等待线程获 得互斥体, 得互斥体,然后接着进行下去 与事件对象类似,互斥体容易创建、打开、 与事件对象类似,互斥体容易创建、打开、使用并 清除。利用CreateMutex() API可创建互斥体 可创建互斥体, 清除。利用CreateMutex() API可创建互斥体,创建 时还可以指定一个初始的拥有权标志, 时还可以指定一个初始的拥有权标志,通过使用这 个标志, 个标志,只有当线程完成了资源的所有的初始化工 作时, 作时,才允许创建线程释放互斥体
• 实验4.1 Windows 2000 线程同步 实验4.1 • 实验4.2 Windows 2000 线程间的通讯 实验4.2 • 实验4.3 Linux 并发程序设计 实验4.3
§4.1 Windows 2000 线程同步
实验估计时间:120分钟,难度系数:4 分钟, 实验估计时间:120分钟 难度系数:
实验目的
在本实验中,通过对事件和互斥体对象的了解,来 在本实验中,通过对事件和互斥体对象的了解, 加深对Windows 2000线程同步的理解 线程同步的理解。 加深对Windows 2000线程同步的理解。
• 回顾系统进程、线程的有关概念,加深对Windows 2000 回顾系统进程、线程的有关概念,加深对Windows 线程的理解 • 了解事件和互斥体对象 • 通过分析实验程序,了解管理事件对象的API 通过分析实验程序,了解管理事件对象的API • 了解在进程中如何使用事件对象 • 了解在进程中如何使用互斥体对象 • 了解父进程创建子进程的程序设计方法
工具/ 工具/准备工作
在开始本实验之前,请回顾教科书的相关内容 在开始本实验之前, 需要做以下准备
• 一台运行Windows 2000 Professional操作系统的计算机 一台运行Windows Professional操作系统的计算机 • 计算机中需安装Visual C++ 6.0专业版或企业版 计算机中需安装Visual 6.0专业版或企业版
背景知识
• CreateFile() 方法除了可访问标准的永久文件外,还可访 方法除了可访问标准的永久文件外, 问控制台输入和输出, 问控制台输入和输出,以及从命名的管道来的数据 • GetFileType() API指明要处理的关键文件句柄的结构。 API指明要处理的关键文件句柄的结构 指明要处理的关键文件句柄的结构。 除此之外,内核还提供了GetFileInformationByHandle() 除此之外,内核还提供了GetFileInformationByHandle() API用于获得关键数据 和GetFileSize() 、GetFileTime() API用于获得关键数据 的详细情况。 的详细情况。其他用于在文件中改变数据的工具函数包 括LockFile() 、SetFilePointer() 和SetEndOfFile() API • 除了这些基于句柄的API之外,内核还提供了大量的工 除了这些基于句柄的API之外 之外, 用于按文件名对文件直接操作。文件对象用完之后, 具,用于按文件名对文件直接操作。文件对象用完之后, 应该用CloseHandle() API加以清除 应该用CloseHandle() API加以清除
背景知识
Windows 2000提供的常用对象可分成三类:核心 2000提供的常用对象可分成三类 提供的常用对象可分成三类: 应用服务、线程同步和线程间通讯。其中, 应用服务、线程同步和线程间通讯。其中,开发人 员可以使用线程同步对象来协调线程和进程的工作, 员可以使用线程同步对象来协调线程和进程的工作, 以使其共享信息并执行任务。 以使其共享信息并执行任务。此类对象包括
背景知识
• 可以使用dwFlagsAndAttributes参数来指定文件的属性 可以使用dwFlagsAndAttributes参数来指定文件的属性 (如只读) ,并确定对数据所执行的读写操作的行为。最 如只读) 并确定对数据所执行的读写操作的行为。 后一个参数hTemplateFile可指定另一个文件对象作为模 后一个参数hTemplateFile可指定另一个文件对象作为模 板,以便为新创建的文件复制属性或扩展属性 • Windows 2000系统中包括许多文件对象的工具函数API 2000系统中包括许多文件对象的工具函数 系统中包括许多文件对象的工具函数API • 通常可以使用ReadFile() 和WriteFile() API在永久存储和 通常可以使用ReadFile() API在永久存储和 应用程序间通过文件对象来移动数据。 应用程序间通过文件对象来移动数据。因为创建调用将 对象的大多数复杂性封装起来了, 对象的大多数复杂性封装起来了,这两个函数只是简单 地利用指向要交换数据的文件对象的句柄 (即指向内存 内的数据缓存区的指针) 然后计数移动数据的字节数。 内的数据缓存区的指针) ,然后计数移动数据的字节数。 除此之外,这两个函数还执行重叠式的输入和输出, 除此之外,这两个函数还执行重叠式的输入和输出,由 于不会“堵塞”主线程, 于不会“堵塞”主线程,可用来传送大量的数据
• 互锁数据 • 临界段 • 事件 • 互斥体 • 信号
背景知识
多线程编程中关键的一步是保护所有的共享资源, 多线程编程中关键的一步是保护所有的共享资源, 工具主要有互锁函数、临界段和互斥体等; 工具主要有互锁函数、临界段和互斥体等;另一个 实质性部分是协调线程使其完成应用程序的任务, 实质性部分是协调线程使其完成应用程序的任务, 为此, 为此,可利用内核中的事件对象和信号 在进程内或进程间实现线程同步的最方便的方法是 使用事件对象,这一组内核对象允许一个线程对其 使用事件对象, 受信状态进行直接控制
操作系统原理实验
进程描述 与控制 ③
调度 ⑤
存储器管理 ⑥
并发性 ④
输入/ 输入/输出 管理 ⑦
文件管理 ⑧
操作系统的各个主题 粗线表示从设计和实现 的角度考虑关系非常紧密
安全性 ⑩
联网 ⑨
实验4 实验4 并发与调度
通过对事件和互斥体对象以及对文件和文件映 射对象的了解,来加深对操作系统进程同步、 射对象的了解,来加深对操作系统进程同步、 线程同步的理解;通过Linux并发程序的调试, Linux并发程序的调试 线程同步的理解;通过Linux并发程序的调试, 学习操作系统并发程序的工作方式
背景知识
• 创建调用比创建事件、互斥体或信号量要复杂。首先必 创建调用比创建事件、互斥体或信号量要复杂。 须在lpFilename中指定对象名 中指定对象名, 须在lpFilename中指定对象名,并且要指向文件系统中 所访问的位置。接着必须用dwDesiredAccess参数提供所 所访问的位置。接着必须用dwDesiredAccess参数提供所 需的访问级别 • 由创建函数要求的共享模式参数dwShareMode可以指定 由创建函数要求的共享模式参数dwShareMode可以指定 当另一进程企图同时访问数据时会发生什么。 当另一进程企图同时访问数据时会发生什么。与所有其 他第一级内核对象一样,可以利用lpSecurityAttributes 他第一级内核对象一样,可以利用lpSecurityAttributes 参数指定所创建对象的安全性。接着, 参数指定所创建对象的安全性。接着,要通过 dwCreationDisposition参数告诉创建函数, dwCreationDisposition参数告诉创建函数,如果数据在 参数告诉创建函数 指定的永久存储介质中存在或不存在时的行为
实验内容与步骤
事件对象 互斥体对象
§4.2 Windows 2000 线程间的通讯
实验估计时间:120分钟,难度系数:5 分钟, 实验估计时间:120分钟 难度系数:
背景知识
Windows 2000提供的线程间通讯类内核对象允 2000提供的线程间通讯类内核对象允 许同一进程或跨进程的线程之间互相发送信息, 许同一进程或跨进程的线程之间互相发送信息, 包括文件、文件映射、邮件位和命名管道等, 包括文件、文件映射、邮件位和命名管道等, 其中最常用的是文件和文件映射。 其中最常用的是文件和文件映射。这类对象允 许一个线程很容易地向同一进程或其他进程中 的另一线程发送信息
背景知识
• 在CreateFileMapping() API中,一个新的文件映射对象 API中 所创建) 需要有一个永久的文件对象 (由CreateFile() 所创建) 。该 函数使用标准的安全性和命名参数, 函数使用标准的安全性和命名参数,还有用于允许操作 (如只读) 的保护标志以及映射的最大容量。随后可根据 如只读) 的保护标志以及映射的最大容量。 来自OpenFileMapping() API的其他线程或进程使用该映 来自OpenFileMapping() API的其他线程或进程使用该映 射——这与事件和互斥体的打开进程是非常类似的 ——这与事件和互斥体的打开进程是非常类似的 • 内存映射文件对象的另一个强大的应用是可请求系统创 建一个运行映射的临时文件。 建一个运行映射的临时文件。该临时文件提供一个临时 的区域,用于线程或进程互相发送大量数据, 的区域,用于线程或进程互相发送大量数据,而不必创 建或保护磁盘上的文件。 建或保护磁盘上的文件。利用向创建函数中发送 INVALID_HANDLE_VALUE来代替真正的文件句柄 INVALID_HANDLE_VALUE来代替真正的文件句柄, 来代替真正的文件句柄, 就可创建这一临时的内存映射文件; 就可创建这一临时的内存映射文件;指令内核使用系统 页式文件来建立支持映射的最大容量的临时数据区
相关文档
最新文档