福大操作系统实验.doc
《福大操作系统实验.doc》由会员分享,可在线阅读,更多相关《福大操作系统实验.doc(26页珍藏版)》请在三一办公上搜索。
1、 计算机操作系统设计实践实验报告学号: 姓名: 学院: 专业: 计算机 年级: 班级: 实验时间:年第一学期指导教师:黄目录计算机操作系统实验一2【实验名称】:2【实验目的】:2【实验原理】:2一、预计结果:2二、实验代码:2三、关键代码分析:2四、实际结果:2五、实验结果分析2计算机操作系统实验二2【实验名称】:2【实验目的】:2【实验原理】:2一、背景知识:2二、设计方案2三、实验代码2四、关键代码分析:2五、实验结果:2六、实验结果分析:2七、对比分析:2计算机操作系统实验三2【实验名称】:2【实验目的】:2【实验原理】:2一、背景知识2二、实验方案(如图):2三、预计实验结果:2四、关
2、键代码:2五、实验代码分析2六、调试过程2七、实验结果:2八、实验结果分析:2计算机操作系统实验一【实验名称】:并发程序设计【实验目的】:掌握在程序中创建新进程的方法, 观察并理解多道程序并发执行的现象。【实验原理】:fork():建立子进程。子进程得到父进程地址空间的一个复制。返回值:成功时,该函数被调用一次,但返回两次,fork()对子进程返回0,对父进程返回子进程标识符(非0值)。不成功时对父进程返回-1,没有子进程。一、预计结果:353535555535553535553535535355535355出现出现出现出现二、实验代码:#include#includevoid main (v
3、oid) int x=5;/* fork调用,创建了一个新的进程, 这个进程共享父进程的数据和堆栈空间等,这之后的代码指令为子进程创建了一个拷贝。 fock 调用是一个复制进程, fock调用后,新进程的入口就在 fock的下一条语句。*/ if( fork( ) )/fork()返回给子进程0,给父进程为子进程的pid x+=30;/父进程执行到,x=35 printf(%dn,x);/输出35 else printf(%dn,x);/子进程执行到,输出5/父进程,子进程都输出,不过输出的是自己空间里的x,父进程35,子进程5 printf(%dn,x); 三、关键代码分析:Linux下一个
4、进程在内存里有三部分的数据,就是代码段、堆栈段和数据段。代码段,顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。堆栈段存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。仔细分析后,我们就可以知道:一个程序一旦调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈
5、段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。fork()不仅创建出与父进程代码相同的子进程,而且父进程在fork执行点的所有上下文场景也被自动复制到子进程中,包括:全局和局部变量打开的文件句柄共享内存、消息等同步对象由进程见并行执行,故父子进程间的输出是乱序的。在经过上百次的实验下,并没有发现全部的预计结果。四、实际结果:五、实验结果分析 现在操作系统在设计时大多都应用了轮转调度算法,也就是说,进程按分配到是时间片执行,当一个进程
6、执行的时间片到了,即使该进程还未执行完就要被挂起,去执行另一个进程。在父进程或子进程执行当中,如果时间片到,则会中断,去执行另一个进程,造成输出结果的交叉。因此就出现了父子进程结果的交叉。 在linux系统中,fork函数创建子进程所需的资源一般是足够的,因此对于子进程创建不成功的情况基本上是不会出现的,而且由于本题的程序耗时很短,因此时间片对于每一个进程也是绝对够用的,因此父子进程结果交叉出现的可能性是比较小的。 计算机操作系统实验二【实验名称】:进程通信(实验2) 【实验目的】:掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。【实验原理
7、】:邮箱机制类似于日常使用的信箱。对于用户而言使用起来比较方便,用户只需使用send()向对方邮箱发邮件 receive()从自己邮箱取邮件, send()和 receive()的内部操作用户无需关心。因为邮箱在内存中实现,其空间有大小限制。其实send()和 receive()的内部实现主要还是要解决生产者与消费者问题。进程A进程B信箱A信箱BSend()Send()receive()receive()【实验内容】:进程通信的邮箱方式由操作系统提供形如send()和receive()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该
8、系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地体现在界面上。在此基础上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱需要有创建、发信、收信、撤销等函数,至少能够支持两个进程互相交换信息,比较自己实现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。一、背景知识:1、信号量机制信号量主要用来控制多个进程对共享资源的访问。当一个进程要访问某个共享资源时,按下列步骤进行:(1) 检测控制这个资源的信号量的值。(2) 如果信号量的值时正数,就可以使用这个资源。进程将信号量的值减一,表示它正在使用资源的某个小单元。(3)
9、 如果信号量的值为零,那么这个进程进入睡眠状态,直到信号量的值重新大于零时被唤醒,转入第一步操作。2、共享内存机制共享内存是允许多个进程共享一块内存,由此来达到交换信息的进程通信机制。共享内存机制是最快的一种进程通信机制。共享内存需要一定的同步机制控制多个进程对同一块内存的读写。当一个进程在写数据时,不允许其他的进程写数据或读数据,这可以通过信号量控制实现。二、设计方案Send共享内存Receive 综合信号量和共享内存机制,用信号量来控制多个进程对共享内存的读写操作,一次只能读写一次。 信号量S1=1,S2=0; Send Receive A: B: P(S1) P(S2) 发送数据或删除数
10、据 读取数据 V(S2) V(S1) GOTO A GOTO B三、实验代码1、系统调用实现邮箱通信程序代码A:#include#include#include#include#include#include#define MSGKEY1 100#define MSGKEY2200typedef struct msgformlong mtype;char mtxt100;msg;/消息结构int main(int agrc,char *argv)msg amsg;int pid,*pint,msgqid1,msgqid2;int cmd,msglen,msgtype;/创建消息队列1用于发送消
11、息给B,或者获得qidmsgqid1 = msgget(MSGKEY1,IPC_CREAT|0666);if(msgqid1 = -1)printf(errorn);return 0;/创建消息队列2用于接收B消息,或者获得qidmsgqid2 = msgget(MSGKEY2,IPC_CREAT|0666);if(msgqid2 = -1)printf(errorn);return 0;while(1)/输入操作命令1代表发送消息,2代表接收消息printf(please input cmd(send = 1,receive = 2)n);scanf(%d,&cmd);if(cmd = 1)
12、/发送消息printf(please input message type:n);scanf(%d,&amsg.mtype);/输入消息类型getchar();printf(please input message:n);scanf(%s,amsg.mtxt);/输入消息msglen = strlen(amsg.mtxt);msgsnd(msgqid1,&amsg,msglen,0);/发送消息if(cmd = 2)/接收消息memset(&amsg,0,sizeof(msg);printf(please input message type:n);scanf(%d,&msgtype);/输入
13、消息类型if(msgrcv(msgqid2,&amsg,100,msgtype,IPC_NOWAIT)= -1)/接收消息printf(msgrcv failed!n);elseprintf(Receive a message from B:ntype: %dn%sn,msgtype,amsg.mtxt);if(cmd = 3)/结束通信,销毁消息队列msgctl(msgqid1,IPC_RMID,0);msgctl(msgqid2,IPC_RMID,0);break;return 0;程序代码B:#include#include#include#include#include#include
14、#define MSGKEY1 100#define MSGKEY2200typedef struct msgformlong mtype;char mtxt100;msg;int main(int argc,char *argv)msg bmsg;int pid,*pint,msgqid1,msgqid2;int cmd,msglen,msgtype;/创建消息队列1用于接收消息,或者获得qidmsgqid1 = msgget(MSGKEY1,IPC_CREAT|0666);if(msgqid1 = -1)printf(error);return 0;/创建消息队列2用于发送消息给A,或者获
15、得qidmsgqid2 = msgget(MSGKEY2,IPC_CREAT|0666);if(msgqid2 = -1)printf(error);return 0;while(1)/输入命令,1代表发送消息,2代表接收printf(please input cmd(send = 1,receive = 2)n);scanf(%d,&cmd);if(cmd = 1) /发送消息printf(please input message type:n);scanf(%d,&bmsg.mtype);/输入消息类型printf(please input message:n);scanf(%s,bmsg
16、.mtxt);/输入消息msglen = strlen(bmsg.mtxt);msgsnd(msgqid2,&bmsg,msglen,0);if(cmd = 2) /接收消息memset(&bmsg,0,sizeof(msg);printf(please input message type:n);scanf(%d,&msgtype);/输入接收的消息类型if(msgrcv(msgqid1,&bmsg,100,msgtype,IPC_NOWAIT) = -1)printf(msgrcv failed!n);elseprintf(Receive the message from A:ntype:
17、 %dn%sn,msgtype,bmsg.mtxt);if(cmd = 3)/命令3销毁队列msgctl(msgqid1,IPC_RMID,0);msgctl(msgqid2,IPC_RMID,0);break;return 0; 2、验证系统调用消息队列实现的邮箱通信A:发送消息B:接收消息B:尝试接收已接收的消息失败:B:连续发送消息A:连续接收消息(逆序接收)删除消息队列-结果:3、自己实现邮箱通信:文件a.c,定义信号量调用结构及信号量操作函数的系统调用形式:#include#include#include#include#include#include#include#define
18、shmsz 256union semun/信号量固定结构 int val; struct semid_ds *buf; unsigned short *array;void init_a_semaphore(int sid,int semnum,int initval) /信号量初始化函数 union semun semopts; semopts.val=initval; semctl(sid,semnum,SETVAL,semopts);/信号量操作函数int semaphore_p(int sem_id)/p操作的封装 struct sembuf sb; sb.sem_num=0; sb.
19、sem_op=-1; sb.sem_flg=SEM_UNDO; if(semop(sem_id,&sb,1)=-1) printf(semaphore_p failed.n); return 0; return 1;int semaphore_v(int sem_id)/v操作的封装 struct sembuf sb; sb.sem_num=0; sb.sem_op=1; sb.sem_flg=SEM_UNDO; if(semop(sem_id,&sb,1)=-1) printf(semaphore_v failed.n); return 0; return 1;文件r.c:读取消息的程序#i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验
链接地址:https://www.31ppt.com/p-2888621.html