ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:22.96KB ,
资源ID:8955131      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-8955131.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(操作系统实验实验二三四.docx)为本站会员(b****8)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

操作系统实验实验二三四.docx

1、操作系统实验实验二三四实验二 进程管理设计一. 目的和要求进程调度是处理机管理的核心内容。本实验要求用C语言编写和调试一个简单的进程调度程序。通过本实验可以加深理解有关进程控制块、进程队列的概念,并体会和了解优先数和时间片轮转调度算法的具体实施办法。二. 实验内容1. 设计进程控制块PCB表结构,分别适用于优先数调度算法和循环轮转算法。PCB结构通常包括以下信息:进程名、进程优先数(或轮转时间片)、进程所占用的CPU时间、进程的状态、当前队列指针等。根据调度算法的不同,PCB结构的内容可以做适当的删除。2. 建立进程就绪队列,对两种不同算法编制入链子程序。3. 编制两种进程调度算法:1)优先数

2、调度;2)循环轮转调度。三. 实验环境1. IBM 286以上微型计算机及其兼容机。2. DOS系统要求3.3及更高的版本。3. TURBO C 2.0。四. 实验要求本实验要求用C 语言编写,选用优先数算法和简单时间片轮转法对五个进程进行调度,每个进程可以有三种状态:运行状态(RUN)、就绪状态(READY)和完成状态(FINISH)。并假定初始状态为就绪状态。五. 模拟算法提示1 数据结构设计进程控制块结构如下:PCB: NAME PRIO/ROUND CPUTIME COUNT NEEDTIME STATE NEXT其中: NAME进程标识符 PRIO进程优先数 ROUND进程轮转时间片

3、 CPUTIME进程占用CPU时间 COUNT计数器 NEEDTIME进程完成还要的CPU时间 STATE进程的状态 NEXT链指针进程控制块链结构中主要指针如下: RUN当前运行进程指针 READY就绪队列头指针 TAIL就绪队列尾指针 FINISH完成队列头指针为了方便处理,程序中进程的运行时间以时间片为单位计算。各进程的优先数或轮转时间片数以及进程需运行的时间片数的初值均由用户给定。2程序说明1)在优先数算法中,进程每执行一次,优先数减3,CPU时间片数加1,进程还需要的时间片数减1。在轮转法中,采用固定时间片,时间片数为2,进程每次执行一次,CPU时间片加2,进程还需要的时间片数减2,

4、并排列就绪队列的尾上。2) 程序结构说明如下:整个程序由FIRSTIN,INSERT1,INSERT2,PRINT,CREAT,PRISCH和ROUNDSCH函数组成。其中: INSERT1的功能是把还未完成且优先数小于别的进程的进程PCB按进程优先数的顺序插入到就绪队列中。 INSERT2是轮转法使用的函数,将执行了一个单位时间片数(为2)且还未完成的进程的PCB插到就绪队列的队尾。 FIRSTIN 的功能是将就绪队列中的第一个进程投入运行。 PRINT打印每执行一个时间片后的所有进程的状态,这里,就绪(等待)用“W”代表。 CREATE 的功能是创建新的进程,即创立进程的PCB,并将此PC

5、B链入到就绪队列中去。 PRISCH按优先数算法调度进程。 ROUNDSCH按时间片轮转法调度进程。 主程序中定义了PCB 的结构和其它变量:number进程数,algo为10个字符长的字符串,存放要求输入的算法的名,PRIORITY 为优先数算法,ROUNDROBIN为循环轮转法,在程序运行时输入其中的一个。3主要算法 算法 PRISCH while (当前运行进程不为空) 进程占用CPU 时间加1 进程到完成还要的CPU时间减1 进程优先数减3 if(进程到完成还要的CPU时间为0) 将该进程插入到完成队列中 修改该进程状态 当前运行进程指针为空 if(就绪队列不为空) FIRSTIN函数

6、 else if (就绪队列不为空且当前进程优先数小于就绪队列中第一 个进程的优先数) 修改当前进程状态为W INSERT1函数 FIRSTIN函数 PRINT函数 算法 ROUNDSCH while (当前运行进程不为空) 进程占用CPU 时间加1 进程到完成还要的CPU时间减1 进程计数器加1 if(进程到完成还要的CPU时间为0) 将该进程插入到完成队列中 修改该进程状态 当前运行进程指针为空 if(就绪队列不为空) FIRSTIN过程 else if (进程计数器等于进程轮转时间片) 修改当前进程计数器为0 if(就绪队列不为空) 修改当前进程状态为W INSERT2过程 FIRSTI

7、N过程 PRINT过程 六. 实验报告1 实验题目。2 采用的数据结构及符号说明。3 打印一份源程序清单,并附加流程图与注释。4 打印出两种算法的执行结果。5 比较两种算法的优缺点并分析实验过程中遇到的问题,谈谈实验后的体会。实验三 进入VI编辑器格式:vi 文件名例 :vi sy.cVi编辑器三种工作方式:1 编辑方式:进入VI 处于编辑方式2 文本输入方式:在编辑方式下输入a ,进入追加方式,输入i,进入插入方式3 命令方式:在输入方式下,按Esc 键,由文本输入转向编辑方式,输入冒号:进入命令方式4 退出vi : wq写文件退出:w wenjianming 写文件: q! 不写退出 :w

8、q! 写退出编译c文件Gcc -o wenjianming.out wenjianming.c运行文件:./wenjianming.out1 实验内容和目的用vi编辑器编辑下列文件,使用gcc编译器和gdb调试器,对下列程序编译运行,分析运行结果。要求至少完成3个程序。2程序示例(1) /* 父子进程之间的同步之例 */#include Main( ) Int pid1;If(pid1=fork() /*create child1 */ if (fork() /*create the child2*/ printf (“parents context.n”); Printf(“parent i

9、s waiting the child1 terminate.n); Wait(0);Printf(“parent is waiting the child2 terminate.n”);Wait(0);Printf(“parent terminate.n”);Exit(0); Else /* child2*/ Printf(“child2s context.n”); Sleep(5); Printf(“ child2 terminate.n”); Exit(0); Else if(pid1=0)/* child1 */ printf(“child1s context.n”); Sleep(1

10、0); Printf(“child1 terminate.n”); Exit(0); 分析: 上述程序是父进程首先创建一个子进程,若成功,再创建另一个子进程,之后三个进程并发执行。究竟谁先执行,是随机的,可根据执行结果判断。试分析该程序的所有运行结果。注释: fork( ) 调用正确完成时,给父进程返回地是被创建子进程的标识,给子进程返回的是0;创建失败时,返回给父进程的时1;Exit(0) 进程终止自己Wait(0) 父进程同步等待子进程结束,即无子进程结束,父进程等待。(2)管道通信机制通过使用管道实现两个和多个进程之间的通信。所谓管道,就是将一个进程的标准输出与另一个进程的标准输入联系在

11、一起,进行通信的一种方法。同组进程之间可用无名管道进行通信,不同组进程可通过有名管道通信。使用无名管道进行父子进程之间的通信 include #include#includeInt pipe( int filedes2);Char parent=”A message to pipe communication.n”;Main() int pid,chan12; Char buf100; Pipe(chan1); Pid=fork();If(pid0) close(chan10); /*父进程关闭读通道*/ Printf(“parent process sends a message to ch

12、ild.n”); Write(chan11,parent,sizeof(parent); Close(chan11); Printf(“parent process waits the child to terminate.n”); Wait(0);Printf(“parent process terminates.n”);Else Close(chan11);/*子进程关闭写通道*/ Read(chan10,buf,100); Printf(“the message read by child process form parent is %s.n”,buf); Close (chan10)

13、; Printf(“child process terminatesn”);观察运行结果。注释:pipe( int filedes2):创建一个无名管道,filedes0为读通道,filedes1为写通道。(3)Linux中的多线程编程threads.c#include #include #include #include #define MAX 10pthread_t thread2;pthread_mutex_t mut;int number=0, i;void *thread1() printf (thread1 : Im thread 1n); for (i = 0; i MAX; i

14、+) printf(thread1 : number = %dn,number); pthread_mutex_lock(&mut); number+; pthread_mutex_unlock(&mut); sleep(2); printf(thread1 :主函数在等我完成任务吗?n); pthread_exit(NULL);void *thread2() printf(thread2 : Im thread 2n); for (i = 0; i MAX; i+) printf(thread2 : number = %dn,number); pthread_mutex_lock(&mut)

15、; number+; pthread_mutex_unlock(&mut); sleep(3); printf(thread2 :主函数在等我完成任务吗?n); pthread_exit(NULL);void thread_create(void) int temp; memset(&thread, 0, sizeof(thread); /comment1 /*创建线程*/ if(temp = pthread_create(&thread0, NULL, thread1, NULL) != 0) /comment2 printf(线程1创建失败!n); else printf(线程1被创建n)

16、; if(temp = pthread_create(&thread1, NULL, thread2, NULL) != 0) /comment3 printf(线程2创建失败); else printf(线程2被创建n);void thread_wait(void) /*等待线程结束*/ if(thread0 !=0) /comment4 pthread_join(thread0,NULL); printf(线程1已经结束n); if(thread1 !=0) /comment5 pthread_join(thread1,NULL); printf(线程2已经结束n); int main()

17、 /*用默认属性初始化互斥锁*/ pthread_mutex_init(&mut,NULL); printf(我是主函数哦,我正在创建线程,呵呵n); thread_create(); printf(我是主函数哦,我正在等待线程完成任务阿,呵呵n); thread_wait(); return 0;注意:Gcc lpthread o thread.out thread.c线程相关操作1) pthread_tpthread_t在头文件/usr/include/bits/pthreadtypes.h中定义: typedef unsigned long int pthread_t; 它是一个线程的标

18、识符。2)pthread_create函数pthread_create用来创建一个线程,它的原型为: extern int pthread_create _P (pthread_t *_thread, _const pthread_attr_t *_attr, void *(*_start_routine) (void *), void *_arg); 第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的

19、线程。对线程属性的设定和修改我们将在下一节阐述。当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。3)pthread_join pthread_exit函数pthread_join用来等待一个线程的结束。函数原型为:extern int pthread_join _P (pthread_t _th, void *_thread_return);第一个参数为被等

20、待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。它的函数原型为:extern void pthread_exit _P (void *_retval) _attribute_ (_noreturn_);唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是NULL

21、,这个值将被传递给 thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。在这一节里,我们编写了一个最简单的线程,并掌握了最常用的三个函数pthread_create,pthread_join和pthread_exit。下面,我们来了解线程的一些常用属性以及如何设置这些属性。互斥锁相关互斥锁用来保证一段时间内只有一个线程在执行一段代码。1) pthread_mutex_init 函数pthread_mutex_init用来生成一个互斥锁。NULL参数表明使用默认属性。如果需要声

22、明特定属性的互斥锁,须调用函数 pthread_mutexattr_init。函数pthread_mutexattr_setpshared和函数 pthread_mutexattr_settype用来设置互斥锁属性。前一个函数设置属性pshared,它有两个取值, PTHREAD_PROCESS_PRIVATE和PTHREAD_PROCESS_SHARED。前者用来不同进程中的线程同步,后者用于同步本进程的不同线程。在上面的例子中,我们使用的是默认属性PTHREAD_PROCESS_ PRIVATE。后者用来设置互斥锁类型,可选的类型有PTHREAD_MUTEX_NORMAL、PTHREAD_

23、MUTEX_ERRORCHECK、 PTHREAD_MUTEX_RECURSIVE和PTHREAD _MUTEX_DEFAULT。它们分别定义了不同的上锁、解锁机制,一般情况下,选用最后一个默认属性。2) pthread_mutex_lock pthread_mutex_unlock pthread_delay_np pthread_mutex_lock声明开始用互斥锁上锁,此后的代码直至调用pthread_mutex_unlock为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行到pthread_mutex_lock处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等

24、待到另一个线程释放此互斥锁。注意:1)需要说明的是,上面的两处sleep不光是为了演示的需要,也是为了让线程睡眠一段时间,让线程释放互斥锁,等待另一个线程使用此锁。下面的参考资料1里头说明了该问题。但是在linux下好像没有pthread_delay_np那个函数(我试了一下,提示没有定义该函数的引用),所以我用了sleep来代替,不过参考资料2中给出另一种方法,好像是通过pthread_cond_timedwait来代替,里头给出了一种实现的办法。2)请千万要注意里头的注释comment1-5,如果没有comment1和comment4,comment5,将导致在pthread_join的时

25、候出现段错误,另外,上面的comment2和comment3是根源所在,所以千万要记得写全代码。因为上面的线程可能没有创建成功,导致下面不可能等到那个线程结束,而在用pthread_join的时候出现段错误(访问了未知的内存区)。另外,在使用memset的时候,需要包含string.h头文件。实验四 1实验内容与目的 熟悉有关文件的系统调用,学习文件系统的系统调用命令,提高对文件系统实现功能的理解和掌握。使用creat open read write 等系统调用用C语言编程实现复制文件。2注释(1) Int creat(const char *pathname, mode_t mode);返回

26、值:如果正确创建,返回文件的描述符;否则返回1;Pathname是要创建文件的路径名。创建文件时,文件只能以只写方式打开Mode 用来规定该文件的拥有者,小组用户和其他用户的访问权限,要求用按位逻辑加对下列符号常量进行所需的组合(同open函数)。(2) int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);int close(int fd);open函数有两个形式.其中pathname是我们要打开的文件名(包含路径名称,缺省是认为在当前路径下面).fla

27、gs可以去下面的一个值或者是几个值的组合.O_RDONLY:以只读的方式打开文件.O_WRONLY:以只写的方式打开文件.O_RDWR:以读写的方式打开文件.O_APPEND:以追加的方式打开文件.O_CREAT:创建一个文件.O_EXEC:如果使用了O_CREAT而且文件已经存在,就会发生一个错误.O_NOBLOCK:以非阻塞的方式打开一个文件.O_TRUNC:如果文件已经存在,则删除文件的内容.前面三个标志只能使用任意的一个.如果使用了O_CREATE标志,那么我们要使用open的第二种形式.还要指定mode标志,用来表示文件的访问权限.mode可以是以下情况的组合.-S_IRUSR 用户

28、可以读 S_IWUSR 用户可以写S_IXUSR 用户可以执行 S_IRWXU 用户可以读写执行-S_IRGRP 组可以读 S_IWGRP 组可以写S_IXGRP 组可以执行 S_IRWXG 组可以读写执行-S_IROTH 其他人可以读 S_IWOTH 其他人可以写S_IXOTH 其他人可以执行 S_IRWXO 其他人可以读写执行-S_ISUID 设置用户执行ID S_ISGID 设置组的执行ID- 我们也可以用数字来代表各个位的标志.Linux总共用5个数字来表示文件的各种权限.00000.第一位表示设置用户ID.第二位表示设置组ID,第三位表示用户自己的权限位,第四位表示组的权限,最后一位表示其他人的权限. 每个数字可以取1(执行权限),2(写权限),4(读权限),0(什么也没有)或者是这几个值的和.比如我们要创建一个用户读写执行,组没有权限,其他人读执行的文件.设置用户ID位那么我们可以使用的模式是-1(设置用户ID)0(组没有设置)7(1+2+4)0(没有权限,使用缺省)5(1+4)即10705:open(temp,O_CREAT,10705); 如果我

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2