2024年操作系统实验报告实验四_第1页
2024年操作系统实验报告实验四_第2页
2024年操作系统实验报告实验四_第3页
2024年操作系统实验报告实验四_第4页
2024年操作系统实验报告实验四_第5页
已阅读5页,还剩20页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

试验四:進程管理(二)试验内容:编写一种程序,打印進程的如下信息:進程標识符,父進程標识符,真实顾客ID,有效顾客ID,真实顾客组ID,有效顾客组ID。并分析真实顾客ID和有效顾客ID的区别。源代码及成果:真实顾客ID和有效顾客ID的区别:真实顾客ID:這個ID就是我們登陆unix系统時的身份ID。有效顾客ID:定义了操作者的权限。有效顾客ID是進程的属性,决定了该進程對文献的访問权限。阅讀如下程序,编译并运行,分析進程执行過程的時间消耗(總共消耗的時间和CPU消耗的時间),并解释执行成果。再编写一种计算密集型的程序替代grep,比较两次時间的花销。注释程序重要語句。/* processusingtime*/#include<stdio.h>#include<stdlib.h>#include<sys/times.h>#include<time.h>#include<unistd.h>voidtime_print(char*,clock_t);intmain(void){//获得進程运行有关的時间clock_tstart,end;structtmst_start,t_end;start=times(&t_start);system(“grepthe/usr/doc/*/*>/dev/null2>/dev/null”);/*command>/dev/null的作用是将是command命令的原则输出丢弃,而原则錯误输出還是在屏幕上。

一般来讲原则输出和原则錯误输出都是屏幕,因此錯误信息還是會在屏幕上输出。>/dev/null2>/dev/null原则输出与原则錯误输出都會被丢弃*///012原则输入原则输出錯误输出//>将信息放到该文献null中end=times(&t_end);time_print(“elapsed”,end-start);puts(“parenttimes”);time_print(“\tuserCPU”,t_end.tms_utime);time_print(“\tsysCPU”,t_end.tms_stime);puts(“childtimes”);time_print(“\tuserCPU”,t_end.tms_cutime);time_print(“\tsysCPU”,t_end.tms_cstime);exit(EXIT_SUCCESS);}voidtime_print(char*str,clock_ttime){longtps=sysconf(_SC_CLK_TCK);/*函数sysconf()的作用為将時钟滴答数转化為秒数,_SC_CLK_TCK為定义每秒钟有多少個滴答的宏*/printf(“%s:%6.2fsecs\n”,str,(float)time/tps);}程序运行成果:由于该程序计算量很小,故消耗的時间比较少,CPU消耗時间均為0.00secs局限性為奇。而進程的执行時间等于顾客CPU時间和系统CPU時间加從硬盘讀取数据時间之和。密集型的程序替代grep:更改為计算密集型的之後就较轻易观测出消耗時间的差异。阅讀下列程序,编译并多次运行,观测执行输出次序,阐明次序相似(或不一样)的原因;观测進程ID,分析進程ID的分派规律。總結fork()的使用措施。注释程序重要語句。/*forkusage*/#include<unistd.h>#include<stdio.h>#include<stdlib.h>intmain(void){pid_tchild;if((child=fork())==-1){perror(“fork”);exit(EXIT_FAILURE);}elseif(child==0){puts(“inchild”);printf(“\tchildpid=%d\n”,getpid());printf(“\tchildppid=%d\n”,getppid());exit(EXIT_SUCCESS);}else{puts(“inparent”);printf(“\tparentpid=%d\n”,getpid());printf(“\tparentppid=%d\n”,getppid());}exit(EXIT_SUCCESS);}程序运行成果:(?)创立進程ID開始時一般随机分派,但若多次运行,或创立子進程時,會次序分派内存。此外,當父進程結束時,子進程尚未結束,则子進程的父進程ID变為1。fork()函数的实质是一种系统调用(和write函数类似),其作用是创立一种新的進程,當一种進程调用它,完毕後就出現两個几乎一模同样的進程,其中由fork()创立的新進程被称為子進程,而本来的進程称為父進程。子進程是父進程的一种拷贝,即子進程從父進程得到了数据段和堆栈的拷贝,這些需要分派新的内存;而對于只讀的代码段,一般使用共享内存方式進行访問。阅讀下列程序,编译并运行,等待或者按^C,分别观测执行成果并分析,注释程序重要語句。flag有什么作用?通過试验阐明。/*usageofkill,signal,wait*/#include<unistd.h>#include<stdio.h>#include<sys/types.h>#include<signal.h>intflag;voidstop();//自定义函数,使flag=0,供signal调用intmain(void){intpid1,pid2;signal(3,stop);//signal()依参数3指定的信号编号来设置该信号的处理函数while((pid1=fork())==-1);//程序等待成功创立子進程事件的发生if(pid1>0){//目前進程為父進程while((pid2=fork())==-1);if(pid2>0){//目前進程為父進程,父進程发出两個中断信号Kill子進程flag=1;sleep(5);kill(pid1,16);//将16指定的信号传給進程ID為pid1的進程kill(pid2,17);//将17指定的信号传給進程ID為pid2的進程wait(0);//临時停止目前進程的执行,直到有信号来到或子進程結束wait(0);printf(“\nparentiskilled\n”);exit(EXIT_SUCCESS);}else{//目前進程為子進程,则发送子進程kill信号,杀死该子進程2flag=1;signal(17,stop);printf(“\nchild2iskilledbyparent\n”);exit(EXIT_SUCCESS);}}else{//目前進程為子進程,则发送子進程kill信号,杀死该子進程1flag=1;signal(16,stop);printf(“\nchild1iskilledbyparent\n”);exit(EXIT_SUCCESS);}}voidstop(){flag=0; }程序运行成果:每個進程(父進程,子進程)均有一种flag,起状态標志作用,flag=1時,表达進程在运行,flag=0,表达進程結束。编写程序,规定父進程创立一种子進程,使父進程和個子進程各自在屏幕上输出某些信息,但父進程的信息總在子進程的信息之後出現。程序源代码:程序运行成果:编写程序,规定父進程创立一种子進程,子進程执行shell命令find/-namehda*的功能,子進程結束時由父進程打印子進程結束的信息。执行中父進程变化子進程的优先级。程序源代码:程序运行成果:/**编写程序,规定父進程创立一种子進程,子進程對一种50*50的字符数组赋值,由父進程变化子進程的优先级,观测不一样优先级進程使用CPU的時间。*/查阅Linux系统中structtask_struct的定义,阐明每项组员的作用。注:searchin/usr/src/linux-2.6/include/linux/sched.h广义上,所有的進程信息被放在一种叫做進程控制块的数据构造中,可以理解為進程属性的集合。每個進程在内核中均有一种進程控制块(PCB)来维护進程有关的信息,Linux内核的進程控制块是task_struct构造体。task_struct是Linux内核的一种数据构造,它會被装载到RAM裏并且包括著進程的信息。每個進程都把它的信息放在task_struct這個数据构造裏,task_struct包括了這些内容:(1)標示符:描述本進程的唯一標示符,用来区别其他進程。(2)状态:任务状态,退出代码,退出信号等。(3)优先级:相對于其他進程的优先级。(4)程序计数器:程序中即将被执行的下一条指令的地址。(5)内存指针:包括程序代码和進程有关数据的指针,尚有和其他進程共享的内存块的指针。(6)上下文数据:進程执行時处理器的寄存器中的数据。(7)I/O状态信息:包括显示的I/O祈求,分派給進程的I/O设备和被進程使用的文献列表。(8)记账信息:也許包括处理器時间總和,使用的時钟数總和,時间限制,记账号。……保留進程信息的数据构造叫做task_struct,并且可以在include/linux/sched.h裏找到它。所有运行在系统裏的進程都以task_struct链表的形式存在内核裏。進程的信息可以通過/proc系统文献夹查看。task_struct某些字段的简介:1.

调度数据组员(1)volatilelongstates;表达進程的目前状态(2)unsignedlongflags;進程標志(3)longpriority;進程优先级。优先级可通過系统调用sys_setpriorty变化。(4)unsignedlongrt_priority;rt_priority給出实時進程的优先级,rt_priority+1000給出進程每次获取CPU後可使用的時间(同样按jiffies计)。实時進程的优先级可通過系统调用sys_sched_setscheduler()变化(見kernel/sched.c)。(5)longcounter;在轮转法调度時表达進程目前還可运行多久。在進程開始运行是被赋為priority的值,後来每隔一种tick(時钟中断)递減1,減到0時引起新一轮调度。重新调度将從run_queue队列选出counter值最大的就绪進程并予以CPU使用权,因此counter起到了進程的動态优先级的作用(priority则是静态优先级)。(6)unsignedlongpolicy;该進程的進程调度方略,可以通過系统调用sys_sched_setscheduler()更改(見kernel/sched.c)。调度方略有:SCHED_OTHER

0

非实時進程,基于优先权的轮转法(roundrobin)。SCHED_FIFO

1

实時進程,用先進先出算法。SCHED_RR

2

实時進程,用基于优先权的轮转法。2.

信号处理(1)unsignedlongsignal;進程接受到的信号。每位表达一种信号,共32种。置位有效。(2)

unsignedlongblocked;進程所能接受信号的位掩码。置位表达屏蔽,复位表达不屏蔽。(3)structsignal_struct*sig;由于signal和blocked都是32位的变量,Linux最多只能接受32种信号。對每种信号,各進程可以由PCB的sig属性选择使用自定义的处理函数,或是系统的缺省处理函数。指派多种信息处理函数的构造定义在include/linux/sched.h中。對信号的检查安排在系统调用結束後,以及“慢速型”中断服务程序結束後(IRQ#_interrupt()。3.

進程队列指针(1)structtask_struct*next_task,*prev_task;所有進程(以PCB的形式)构成一种双向链表。next_task和就是链表的前後指针。链表的頭和尾都是init_task(即0号進程)。(2)structtask_struct*next_run,*prev_run;由正在运行或是可以运行的,其進程状态均為TASK_RUNNING的進程所构成的一种双向循环链表,即run_queue就绪队列。该链表的前後向指针用next_run和prev_run,链表的頭和尾都是init_task(即0号進程)。(3)structtask_struct*p_opptr,*p_pptr;和structtask_struct*p_cptr,*p_ysptr,*p_osptr;以上分别是指向原始父進程(originalparent)、父進程(parent)、子進程(youngestchild)及新老兄弟進程(youngersibling,oldersibling)的指针。4.

進程標识(1)unsignedshortuid,gid;uid和gid是运行進程的顾客標识和顾客组標识。(2)intgroups[NGROUPS];与多数現代UNIX操作系统同样,Linux容許進程同步拥有一组顾客组号。在進程访問文献時,這些组号可用于合法性检查。(3)unsignedshorteuid,egid;euid和egid又称為有效的uid和gid。出于系统安全的权限的考虑,运行程序時要检查euid和egid的合法性。一般,uid等于euid,gid等于egid。有時候,系统會赋予一般顾客临時拥有root的uid和gid(作為顾客進程的euid和egid),以便于進行运作。(4)unsignedshortfsuid,fsgid;fsuid和fsgid称為文献系统的uid和gid,用于文献系统操作時的合法性检查,是Linux独特的標识类型。它們一般分别和euid和egid一致,但在NFS文献系统中NFS服务器需要作為一种特殊的進程访問文献,這時只修改客户進程的fsuid和fsgid。(5)unsignedshortsuid,sgid;suid和sgid是根据POSIX原则引入的,在系统调用变化uid和gid時,用于保留真正的uid和gid。(6)intpid,pgrp,session;進程標识号、進程的组织号及session標识号,有关系统调用(見程序kernel/sys.c)有sys_setpgid、sys_getpgid、sys_setpgrp、sys_getpgrp、sys_getsid及sys_setsid几种。(7)intleader;与否是session的主管,布尔量。5.

時间数据组员(1)unsignedlongtimeout;用于软件定期,指出進程间隔多久被重新唤醒。采用tick為單位。(2)unsignedlongit_real_value,it_real_iner;用于itimer(intervaltimer)软件定期。采用jiffies為單位,每個tick使it_real_value減到0時向進程发信号SIGALRM,并重新置初值。初值由it_real_incr保留。详细代码見kernel/itimer.c中的函数it_real_fn()。(3)structtimer_listreal_timer;一种定期器构造(Linux共有两种定期器构造,另一种称作old_timer)。数据构造的定义在include/linux/timer.h中,有关操作函数見kernel/sched.c中add_timer()和del_timer()等。(4)unsignedlongit_virt_value,it_virt_incr;有关進程顾客态执行時间的itimer软件定期。采用jiffies為單位。進程在顾客态运行時,每個tick使it_virt_value減1,減到0時向進程发信号SIGVTALRM,并重新置初值。初值由it_virt_incr保留。详细代码見kernel/sched.c中的函数do_it_virt()。(5)unsignedlongit_prof_value,it_prof_incr;同样是itimer软件定期。采用jiffies為單位。不管進程在顾客态或内核态运行,每個tick使it_prof_value減1,減到0時向進程发信号SIGPROF,并重新置初值。初值由it_prof_incr保留。详细代码見kernel/sched.c中的函数do_it_prof。(6)longutime,stime,cutime,cstime,start_time;以上分别為進程在顾客态的运行時间、進程在内核态的运行時间、所有层次子進程在顾客态的运行時间總和、所有层次子進程在关键态的运行時间總和,以及创立该進程的時间。6.

信号量数据组员(1)structsem_undo*semundo;進程每操作一次信号量,都生成一种對本次操作的undo操作,它由sem_undo构造描述。這些属于同一進程的undo操作构成的链表就由semundo属性指示。當進程异常终止時,系统會调用undo操作。sem_undo的组员semadj指向一种数据数组,表达各次undo的量。构造定义在include/linux/sem.h。(2)structsem_queue*semsleeping;每一信号量集合對应一种sem_queue等待队列(見include/linux/sem.h)。進程因操作该信号量集合而阻塞時,它被挂到semsleeping指示的有关该信号量集合的sem_queue队列。反過来,semsleeping。sleeper指向该進程的PCB。7.

進程上下文环境(1)structdesc_struct*ldt;進程有关CPU段式存储管理的局部描述符表的指针,用于仿真WINEWindows的程序。其他状况下取值NULL,進程的ldt就是arch/i386/traps.c定义的default_ldt。(2)structthread_structtss;任务状态段,其内容与IN

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论