操作系统实验三
操作系统实验,实验3, 进程管理 (1)

在图形界面上利用终端通过命令“su - ”切换到超级用户,编辑文件 “job”; 按组合键[Ctrl+Alt+F2]切换到第二个虚拟终端(超级用户); 输入命令“at –f job now+1 minute”,设置1分钟后执行at调度内容; 稍等后观察at调度的执行效果,再切换到第一个虚拟终端观察at调度 的执行效果;
切换到第一个虚拟终端观察at调度的执行效果(5分钟后系统将执行重 启调度任务)。
[操作要求2] 设置一个调度,要求1分钟后执行文件job中的作业。 文件job的内容为: find /home/jkx/ -name “*.c” > /home/jkx/fdresult wall user jkx, all code files have been searched out! Please check out. [操作步骤]
续表
守 护 进 程 innd Usenet新闻服务器 功 能 说 明
linuxconf
lpd named netfs network
允许使用本地WEB服务器作为用户接口来配置机器
打印服务器 DNS服务器 安装NFS、Samba和NetWare网络文件系统 激活已配置网络接口的脚本程序
nfsd
portmap postgresql routed sendmail
事件(例如xinetd和lpd)
启动守护进程有如下几种方法
在引导系统时启动 人工手动从shell提示符启动
系统启动script的执行期间 被启动(/etc/rc.d) 任何具有相应执行 权限的用户
使用crond守护进程启动
执行at命令启动
守护进程一般由系统在开机时通过脚本或root
操作系统实验3-进程控制

WORD wMajorReq=(WORD)(dwVerReq>16);
WORD wMinorReq=(WORD)(dwVerReq&0xffff);
::cout<<"Process ID:"<<dwIdThis<<",requires OS:"<<wMajorReq<<wMinorReq<<::endl;
{
//改变优先级
::SetPriorityClass(
::GetCurrentProcess(), //利用这一进程
HIGH_PRIORITY_CLASS); //改变为high
//报告给用户
::cout<<"Task Manager should indicate this "
"process is high priority."<<::endl;
//设置版本信息的数据结构,以便保存操作系统的版本信息
OSVERSIONINFOEX osvix;
::ZeroMemory(&osvix,sizeof(osvix));
osvix.dwOSVersionInfoSize=sizeof(osvix);
//提取版本信息和报告
::GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osvix));
Parent();
}
return 0;
}
分析:程序4-3.cpp说明了一个进程从“生”到“死”的整个一生,第一次执行时,它创建一个子进程,其行为如同“父亲”。在创建子进程之前,先创建一个互斥的内核对象,其行为对于子进程来说,如同一个“自杀弹”。当创建子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同时等待着父进程使用ReleaseMutex()API发出“死亡”信号。然后用Sleep()API调用来模拟父进程处理其他工作,等完成时,指令子进程终止。
哈工大《操作系统》实验3

向kernel/printk.c中添加日志打印功能,将以下代码添加到原文件中:
在kernel/fork.c、kernel/sched.c和kernel/exit.c中,找到正确的状态转换点,并添加合适的状态信息,把它输出到log文件之中。
fork.c的修改如下:
exit.c的修改如下:
sched.c的修改如下:
在虚拟机上运行ls -l /var”或“ll /var”查看process.log是否建立,及它的属性和长度;
修改时间片
include/linux/sched.h宏INIT_TASK中定义的:
0,15,15, 分别对应state、counter和priority,将priority值修改,即可实现对时间片大小的调整。
0,15,15, 分别对应state、counter和priority,
priority值修改,即可实现对时间片大小的调整。
在修改时间片将priority由15改为150后,Process 9~20 中Turnaround, Waiting, CPU Burst, I/O Burst变化不大,原因可能是程序中I/O操作占用的时间对于总时间影响的权重过大,导致处理时间体现的并不明显。
或者变化不大的原因是,子进程连续占用cpu的时间要比时间片大很多。
操作系统实验三 时间片轮转法完成进程调度

实验三:时间片轮转法完成进程调度一、实验目的:(1)加深对进程的理解(2)理解进程控制块的结构(3)理解进程运行的并发性(4)掌握时间片轮转法进程调度算法实验内容:(1)建立进程控制块(2)设计三个链队列,分别表示运行队列、就绪队列和完成队列(3)用户输入进程标识符以及进程所需的时间,申请空间存放进程PCB信息。
(4)每一个时间片结束输出各进程的进程号,CPU时间(即已经占用的CPU时间),所需时间(即还需要的CPU时间),以及状态(即用W表示等待,R表示运行,F表示完成)实验程序:#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct node{char name[10];/*进程标识符*/int prio;/*进程优先数*/int round;/*进程时间轮转时间片*/int cputime; /*进程占用CPU时间*/int needtime; /*进程到完成还要的时间*/int count;/*计数器*/char state; /*进程的状态*/struct node *next; /*链指针*/}PCB;PCB *finish,*ready,*tail,*run; //队列指针int N,t; //进程数,时间片的大小void firstin(){run=ready;//就绪队列头指针赋值给运行头指针run->state='R'; //进程状态变为运行态ready=ready->next; //就绪队列头指针后移到下一进程}void prt1(char a)//输出标题函数{if(toupper(a)=='P')//优先级法printf("进程名占用CPU时间到完成还要的时间轮转时间片状态\n");} void prt2(char a,PCB *q)//进程PCB输出{if(toupper(a)=='P')//优先级法的输出printf("%4s %8d %12d %14d %8c\n",q->name,q->cputime,q->needtime,q->roun d,q->state);}void prt(char algo)//输出函数二、三、{PCB *p;prt1(algo);//输出标题if(run!=NULL)//如果运行指针不空prt2(algo,run);//输出当前正在运行的PCBp=ready;//输出就绪队列PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}p=finish;//输出完成队列的PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}getchar(); //按住任意键继续}void insert(PCB *q)//时间片轮转的插入算法{PCB *p1,*s,*r;s=q;//待插入的PCB指针p1=ready;//就绪队列头指针r=p1;//*r做pl的前驱指针while(p1!=NULL)if(p1->round<=s->round){r=p1;p1=p1->next;}if(r!=p1){r->next=s;s->next=p1;}else{s->next=p1;//否则插入在就绪队列的头ready=s;}}void create(char alg)//时间片轮转法创建链表进程PCB{PCB *p;int i,time;char na[10];ready=NULL;finish=NULL;run=NULL;printf("输入进程名及其需要运行的时间(中间以空格隔开):\n"); for(i=1;i<=N;i++){p=new PCB;scanf("%s %d",&na,&time);strcpy(p->name,na);p->cputime=0;p->needtime=time;p->state='W';//进程的状态p->round=0;if(ready!=NULL)insert(p);else{p->next=ready;ready=p;}}printf("*************时间片轮转法进程调度过程*************\n"); prt(alg);run=ready;ready=ready->next;run->state='R';}void timeslicecycle(char alg)//时间片轮转法{while(run!=NULL){run->cputime=run->cputime+t;//处理时间加trun->needtime=run->needtime-t;//完成需要时间减trun->round=run->round+t;//运行完将其变为完成态,插入完成队列if(run->needtime<=0)//当进程完成时{run->next=finish;finish=run;run->state='F';run=NULL;if(ready!=NULL)//就绪队列不空,将第一个进程投入进行firstin();}else{run->state='W';//将进程插入到就绪队列中等待轮转insert(run);//将就绪队列的第一个进程投入运行firstin();}prt(alg);}}void main()//主函数{char algo='P';//算法标记printf("输入进程的个数:");scanf("%d",&N);//输入进程数printf("定义时间片大小:");scanf("%d",&t);//输入时间片大小create(algo);//创建进程timeslicecycle(algo);//时间片轮转法调度}//main()四、实验结果:五、实验小结:时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。
电大操作系统实验报告3_ 进程管理实验

电大操作系统实验报告3_ 进程管理实验电大操作系统实验报告 3 进程管理实验一、实验目的进程管理是操作系统的核心功能之一,本次实验的目的是通过实际操作和观察,深入理解进程的概念、状态转换、进程调度以及进程间的通信机制,掌握操作系统中进程管理的基本原理和方法,提高对操作系统的整体认识和实践能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C 语言,开发工具为 Visual Studio 2019。
三、实验内容及步骤(一)进程的创建与终止1、编写一个 C 程序,使用系统调用创建一个子进程。
2、在父进程和子进程中分别输出各自的进程 ID 和父进程 ID。
3、子进程执行一段简单的计算任务,父进程等待子进程结束后输出结束信息。
以下是实现上述功能的 C 程序代码:```cinclude <stdioh>include <stdlibh>include <unistdh>int main(){pid_t pid;pid = fork();if (pid < 0) {printf("创建子进程失败\n");return 1;} else if (pid == 0) {printf("子进程:我的进程 ID 是%d,父进程 ID 是%d\n",getpid(), getppid());int result = 2 + 3;printf("子进程计算结果:2 + 3 =%d\n", result);exit(0);} else {printf("父进程:我的进程 ID 是%d,子进程 ID 是%d\n",getpid(), pid);wait(NULL);printf("子进程已结束\n");}return 0;}```编译并运行上述程序,可以观察到父进程和子进程的输出信息,验证了进程的创建和终止过程。
(二)进程的状态转换1、编写一个 C 程序,创建一个子进程,子进程进入睡眠状态一段时间,然后被唤醒并输出状态转换信息。
操作系统实验3进程的创建控制实验

操作系统实验3进程的创建控制实验实验三的目标是通过实现一个进程控制程序,来加深我们对进程创建和控制机制的理解,并通过实践来熟悉和掌握相关的编程技巧。
在进行实验之前,我们需要先了解进程的一些基本概念和相关知识。
首先,进程的创建是通过操作系统中的系统调用来完成的。
在Linux系统中,常用的创建进程的系统调用有fork(和exec(。
fork(系统调用可以创建一个新的进程,该进程与调用fork(的进程几乎完全相同;而exec(系统调用则在新创建的进程中执行一个新的程序。
另外,进程的控制机制主要是通过进程的状态来实现的。
进程可以处于就绪状态、运行状态和阻塞状态。
就绪状态的进程可以被调度器选择后立即运行,而阻塞状态的进程则需要等待一些条件满足后才能被唤醒并变为就绪状态。
实验三的具体内容包括:1. 编写一个程序,通过调用fork(创建多个子进程。
子进程和父进程可以并行执行,共享程序的代码和数据段。
2. 子进程通过调用exec(系统调用执行不同的程序。
可以通过调用不同的exec(函数或者传入不同的参数来执行不同的程序。
3. 子进程执行的程序可能会产生不同的结果,比如输出不同的字符串或者产生不同的返回值。
我们可以通过wait(系统调用等待子进程退出,并获取子进程的返回值。
4. 父进程可以通过调用waitpid(系统调用来选择等待一些特定的子进程,以及获取特定子进程的返回值。
通过实验三的实践,我将更加深入地了解进程的创建和控制机制。
实验三的实验结果将让我熟悉和掌握相关的编程技巧,为我今后更加熟练地编写和控制进程打下坚实的基础。
总之,实验三是一个非常有意义的实验,将帮助我更加深入地理解进程的创建和控制机制,并通过实践获得相关的编程技巧。
这将对我今后的学习和实践有很大的帮助。
16207318邓嘉操作系统实验三

操作系统实验第三次实验进程同步实验指导老师:***学号:********姓名:***操作系统第三次实验进程同步实验指导老师:谭朋柳学生:16207318邓嘉4.1 实验目的加深对并发协作进程同步与互斥概念的理解,观察和体验并发进程同步与互斥操作的效果,分析与研究经典进程同步与互斥问题的实际解决方案。
了解Linux 系统中IPC 进程同步工具的用法,练习并发协作进程的同步与互斥操作的编程与调试技术。
4.2 实验说明在linux 系统中可以利用进程间通信(interprocess communication )IPC 中的3 个对象:共享内存、信号灯数组、消息队列,来解决协作并发进程间的同步与互斥的问题。
1)共享内存是OS 内核为并发进程间交换数据而提供的一块内存区(段)。
如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映射到自己私有的地址空间中。
如果一进程更新了段中数据,那么其他进程立即会看到这一更新。
进程创建的段也可由另一进程读写。
linux 中可用命令ipcs -m 观察共享内存情况。
$ ipcs -m------ Shared Memory Segments --------key shmid owner perms bytes nattch status 0x00000000 327682 student 600 393216 2 dest0x00000000 360451 student 600 196608 2 dest 0x00000000 393220 student 600 196608 2 destkey 共享内存关键值shmid 共享内存标识owner 共享内存所由者(本例为student)perm 共享内存使用权限(本例为student 可读可写)byte 共享内存字节数nattch 共享内存使用计数status 共享内存状态上例说明系统当前已由student 建立了一些共享内存,每个都有两个进程在共享。
操作系统教学实践(3篇)

第1篇一、引言操作系统是计算机科学与技术领域的重要基础课程,它涉及计算机系统的资源管理、进程管理、存储管理、文件系统等多个方面。
为了提高学生对操作系统的理解和掌握程度,本文将从教学实践的角度,探讨如何进行操作系统教学。
二、教学目标1. 使学生掌握操作系统的基本概念、原理和关键技术;2. 培养学生分析和解决实际问题的能力;3. 增强学生的团队协作和创新能力;4. 提高学生的编程能力和动手能力。
三、教学内容1. 操作系统概述:介绍操作系统的定义、发展历程、分类和特点;2. 进程管理:讲解进程的概念、进程状态、进程调度算法和进程同步与互斥;3. 存储管理:分析内存分配策略、页面置换算法和虚拟内存技术;4. 文件系统:探讨文件系统的概念、目录结构、文件操作和存储设备管理;5. 设备管理:介绍设备的分类、驱动程序、I/O控制方式和中断处理;6. 网络操作系统:讲解网络操作系统的基本概念、网络协议、网络设备管理和网络安全。
四、教学实践1. 案例教学:通过实际案例,引导学生分析操作系统的原理和应用。
例如,以Linux系统为例,讲解进程调度、内存管理和文件系统等知识点。
2. 实验教学:设计实验项目,让学生动手实践操作系统的相关知识。
实验项目包括:(1)进程调度实验:让学生编写进程调度算法,实现进程的创建、调度和同步。
(2)内存管理实验:让学生实现内存分配、页面置换和虚拟内存等技术。
(3)文件系统实验:让学生实现文件系统的目录结构、文件操作和存储设备管理。
(4)设备管理实验:让学生编写设备驱动程序,实现设备的控制和管理。
3. 项目教学:以实际项目为背景,让学生分组完成项目开发。
项目可以包括:(1)操作系统模拟器:让学生模拟操作系统的运行过程,加深对操作系统原理的理解。
(2)嵌入式操作系统开发:让学生了解嵌入式操作系统的特点,掌握嵌入式开发技能。
(3)分布式操作系统开发:让学生了解分布式系统的原理,掌握分布式操作系统的开发方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
天津理工大学实验报告#include<iostream>#include<ctime>using namespace std;void FCFS(int a[],int n);void SSTF(int a[],int n);void SCAN(int a[],int n);void CSCAN(int a[],int n);int main(){int n;//磁道的个数int s;//功能号cout<<"请输入磁道的个数:"<<endl;cin>>n;int *a=new int[n];cout<<"生成随机磁道号..."<<endl;srand((unsigned)time(NULL));for(int i=0;i<n;i++){a[i]=(rand()%100)+1;cout<<a[i]<<" "; }cout<<endl;while(1) {cout<<endl;cout<<"1、先来先服务算法(FCFS)"<<endl;cout<<"2、最短寻道时间算法(SSTF)"<<endl;cout<<"3、扫描算法(SCAN)"<<endl;cout<<"4、循环扫描算法(CSCAN)"<<endl;cout<<"0、退出"<<endl;cout<<endl;cout<<"请选择功能号:";cin>>s;if(s>4){cout<<"输入有误!"<<endl;}else{switch(s){ case 0: exit(0);break ; case 1:FCFS(a,n); break;case 2:SSTF(a, n);break;case 3:SCAN(a, n);break;case 4:CSCAN(a,n);break; } }} return 0; }//先来先服务调度算法(FCFS)void FCFS(int a[],int n){int sum=0,j,i,first=0,now;cout<<"请输入当前磁道号:";cin>>now;//确定当前磁头所在位置cout<<"磁盘调度顺序为:"<<endl;for( i=0;i<n;i++)//按访问顺序输出磁道号{cout<<a[i]<<" ";}//计算sumfor(i=0,j=1;j<n;i++,j++){first+=abs(a[j]-a[i]);//外围磁道与最里面磁道的距离}sum+=first+abs(now-a[0]);cout<<endl;cout<<"移动的总磁道数: "<<sum<<endl;}//最短寻道时间算法(SSTF)void SSTF(int a[],int n){int temp;int k=1;int now,l,r;int i,j,sum=0;//将磁道号按递增排序for(i=0;i<n;i++)for(j=i+1;j<n;j++){if(a[i]>a[j]){temp=a[i];a[i]=a[j];a[j]=temp; }}cout<<"按递增顺序排好的磁道:"<<endl;for( i=0;i<n;i++){cout<<a[i]<<" ";//输出排好的磁道顺序}cout<<endl;cout<<"请输入当前的磁道号:";cin>>now;//确定当前磁头所在位置cout<<"磁盘调度顺序为:"<<endl;if(a[n-1]<=now)//当前磁头位置大于最外围欲访问磁道{for(i=n-1;i>=0;i--)cout<<a[i]<<" ";sum=now-a[0];}elseif(a[0]>=now)//当前磁头位置小于最里欲访问磁道{for(i=0;i<n;i++)cout<<a[i]<<" ";sum=a[n-1]-now;}else{while(a[k]<now)//确定当前磁道在已排的序列中的位置{k++;}l=k-1;//在磁头位置的前一个欲访问磁道r=k;//磁头欲访问磁道while((l>=0)&&(r<n)){if((now-a[l])<=(a[r]-now))//选择离磁头近的磁道 {cout<<a[l]<<" ";sum+=now-a[l];now=a[l];l=l-1; }else{cout<<a[r]<<" ";sum+=a[r]-now;now=a[r];r=r+1;} }if(l=-1)//磁头位置里侧的磁道已访问完{for(j=r;j<n;j++)//访问磁头位置外侧的磁道{cout<<a[j]<<" ";}sum+=a[n-1]-a[0];}if(r==n)//磁头位置外侧的磁道已访问完{for(j=k-1;j>-1;j--) //访问磁头位置里侧的磁道{cout<<a[j]<<" ";}sum+=a[n-1]-a[0];} }cout<<endl;cout<<"移动的总道数:"<<sum<<endl;}//扫描算法(SCAN)void SCAN(int a[],int n){int temp;int k=1;int now,l,r;int i,j,sum=0;for(i=0;i<n;i++)//对访问磁道按由小到大顺序排列输出 for(j=i+1;j<n;j++){if(a[i]>a[j]){temp=a[i];a[i]=a[j];a[j]=temp;}}cout<<"按递增顺序排好的磁道:"<<endl;for( i=0;i<n;i++){cout<<a[i]<<" ";}cout<<endl;cout<<"请输入当前的磁道号:";cin>>now;//以下算法确定磁道访问顺序if(a[n-1]<=now) //磁头位置大于最外围欲访问磁道{for(i=n-1;i>=0;i--)cout<<a[i]<<" ";sum=now-a[0];}elseif(a[0]>=now) //磁头位置小于最里欲访问磁道{for(i=0;i<n;i++)cout<<a[i]<<" ";sum=a[n-1]-now;}else //磁头位置在最里侧磁道与最外侧磁道之间{ int d;while(a[k]<now){ //确定当前磁道在已排的序列中的位置k++;}l=k-1;//在磁头位置的前一个欲访问磁道r=k; //磁头欲访问磁道cout<<"请输入当前磁头移动的方向 (0 表示向内,1表示向外) : "; cin>>d; //确定磁头访问的方向cout<<"磁盘调度顺序为:";if(d==0||d==1){if(d==0) //磁头向内{for(j=l;j>=0;j--){cout<<a[j]<<" ";}for(j=r;j<n;j++){cout<<a[j]<<" ";}sum=now-2*a[0]+a[n-1];}if(d==1) //磁头向外{for(j=r;j<n;j++){cout<<a[j]<<" ";}for(j=l;j>=0;j--){cout<<a[j]<<" ";}sum=2*a[n-1]-now-a[0];}}elsecout<<"请输入0或1!"<<endl;}cout<<endl;cout<<"移动的总道数: "<<sum<<endl;}//循环扫描算法(CSCAN)void CSCAN(int a[],int n){int temp;int now,l,r;int i,j,sum=0;int k=1;for(i=0;i<n;i++)//对访问磁道按由小到大顺序排列输出for(j=i+1;j<n;j++){if(a[i]>a[j]){temp=a[i];a[i]=a[j];a[j]=temp;}}cout<<"按递增顺序排好的磁道:"<<endl;for( i=0;i<n;i++){cout<<a[i]<<" ";}cout<<endl;cout<<"请输入当前的磁道号:";cin>>now;//确定当前磁道号if(a[n-1]<=now)//磁头位置大于最外围欲访问磁道{for(i=0;i<n;i++)cout<<a[i]<<" ";sum=now-2*a[0]+a[n-1];}elseif(a[0]>=now)//磁头位置小于最里欲访问磁道{for(i=0;i<n;i++)cout<<a[i]<<" ";sum=a[n-1]-now;}else //磁头位置在最里侧磁道与最外侧磁道之间{ int d;while(a[k]<now){k++;}l=k-1;//在磁头位置的前一个欲访问磁道r=k; //磁头欲访问磁道cout<<"请输入当前磁头移动的方向 (0 表示向内,1表示向外) : "; cin>>d; //确定磁头访问的方向cout<<"磁盘调度顺序为:";if(d==0||d==1){if(d==1) //磁头向外侧访问{for(j=r;j<n;j++)//先访问外侧磁道再转向最里欲访问磁道{cout<<a[j]<<" ";}for(j=0;j<r;j++){cout<<a[j]<<" ";}sum=2*a[n-1]-now-2*a[0]+a[l];}if(d==0) //磁头向内侧访问{for(j=r-1;j>=0;j--){cout<<a[j]<<" ";}for(j=n-1;j>=r;j--)//{cout<<a[j]<<" ";}sum=2*a[n-1]-2*a[0]+now-a[r];}}elsecout<<"请输入0或1!";}cout<<endl;cout<<"移动的总道数: "<<sum<<endl;}实验结果:1.先来先服务算法(FCFS)测试结果2.最短寻道时间算法(SSTF)测试结果3.循环扫描算法(SCAN)测试结果4.循环扫描算法(CSCAN)测试结果通过这次实验,我发现SSTF总道最少,性能最好,速度最快,其余性能并不是那么好。