操作系统实验_示例代码_linux_第1页
操作系统实验_示例代码_linux_第2页
操作系统实验_示例代码_linux_第3页
操作系统实验_示例代码_linux_第4页
操作系统实验_示例代码_linux_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

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

文档简介

1、计算机操作系统实验指导苏州科技学院电子与信息工程系软件教研室二OO二年九月示例代码第一部分 LINUX 操作系统平台实验一 命令解释程序示例程序minishell.c/文 件 名 minishell.cpp/功 能小型SHELL命令解释程序 /开发环境 #define true 1#define flase 0#include #include #include void main()char cmdl80;char *scwt=exit,dir,time;static int cmdnum=3;/可用的命令数char cmd80;int j,n;while(true)printf(Pleas

2、e input command: );gets(cmdl);/取命令行输入n=strcspn(cmdl, );/取命令命令部分if (n0|strlen(cmdl)0) strncpy(cmd,cmdl,n);cmdn=0;for(j=0;jcmdnum;j+)if (strcmp(cmd,scwtj)=0)break;if (j=0)/是exit命令?exit(0);if (jcmdnum)/其他合法命令system(cmdl);continue;printf(Bad command!n); /命令错实验二 进程管理fork()调用示例#include main()int p1,p2;whi

3、le (p1=fork()=-1);if (p1=0)/是子进程?putchar(b);else/父进程putchar(a);实验三 进程间通信1)pipe()调用示例#includemain()int id,fd2;char buf50,s50;pipe(fd);while (id=fork()=-1);if (id=0)sprintf(buf,Child is sending message!);write(fd1,buf,50);exit(0);else wait(0);read(fd0,s,50);printf(%sn,s);exit(0);2)共享存储器示例shm_sample.c#

4、include #include #include #include #define SEGSIZE 100main(int argc, char *argv) key_t key;int shmid, cntr;char *segptr;if(argc = 1)usage(); /* Create unique key via call to ftok() */key = ftok(., S);/* Open the shared memory segment - create if necessary */if(shmid = shmget(key, SEGSIZE, IPC_CREAT|

5、IPC_EXCL|0666) = -1)printf(Shared memory segment exists - opening as clientn);/* Segment probably already exists - try as a client */if(shmid = shmget(key, SEGSIZE, 0) = -1)perror(shmget);exit(1);elseprintf(Creating new shared memory segmentn);/* Attach (map) the shared memory segment into the curre

6、nt process */if(segptr = shmat(shmid, 0, 0) = -1)perror(shmat);exit(1);switch(tolower(argv10)case w: writeshm(shmid, segptr, argv2);break;case r: readshm(shmid, segptr);break;case d: removeshm(shmid);break;case m: changemode(shmid, argv2);break;default: usage();writeshm(int shmid, char *segptr, char

7、 *text)strcpy(segptr, text);printf(Done.n);readshm(int shmid, char *segptr)printf(segptr: %sn, segptr);removeshm(int shmid)shmctl(shmid, IPC_RMID, 0);printf(Shared memory segment marked for deletionn);changemode(int shmid, char *mode) struct shmid_ds myshmds;/* Get current values for internal data s

8、tructure */shmctl(shmid, IPC_STAT, &myshmds); /* Display old permissions */printf(Old permissions were: %on, myshmds.shm_perm.mode);/* Convert and load the mode */sscanf(mode, %o, &myshmds.shm_perm.mode); /* Update the mode */shmctl(shmid, IPC_SET, &myshmds);printf(New permissions are : %on, myshmds

9、.shm_perm.mode);usage()fprintf(stderr, shm_sample - A utility for tinkering with shared memoryn);fprintf(stderr, nUSAGE: shmtool (w)rite n);fprintf(stderr, (r)eadn);fprintf(stderr, (d)eleten);fprintf(stderr, (m)ode change n);exit(1);3)消息队列使用示例(1) message.h/* message.h*/#ifndef MESSAGE_H#define MESSA

10、GE_Hstruct mymsgbuflong mtype;char mtext256;#endif(2) msg_server.c/*msg_server.c*/#include #include #include #include #include #include #include message.hint msqid=-1;void sig_handle(int signo)/*软中断*/if (msqid!=-1)msgctl(msqid,IPC_RMID,NULL); printf(server quit.n);exit(0);int main()struct mymsgbuf m

11、sgbuf;int left,right;char c; int length;if (msqid=msgget(999,0666)!=-1)msgctl(msqid,IPC_RMID,NULL);if (msqid=msgget(999,IPC_CREAT|0666)=-1)printf(error:getmsgn);exit(1);signal(SIGINT,sig_handle); /*LINUX置软中断CTRL-D*/for (;) if (msgrcv(msqid,&msgbuf,256,1L,0)=-1) printf(error:msgrcvn); exit(1); length

12、=strlen(msgbuf.mtext); left=0; right=length-1; while(leftright) c=msgbuf.mtextleft; msgbuf.mtextleft=msgbuf.mtextright; msgbuf.mtextright=c; left+; right-; msgbuf.mtextlength=0; msgbuf.mtype=2; if (msgsnd(msqid,&msgbuf,256,0)=-1) printf(error:msgsnd); exit(1); msgctl(msqid,IPC_RMID,NULL);exit(0);(3)

13、 msg_client.c/*msg_client.c*/#include #include #include #include #include #include message.hint main()struct mymsgbuf msgbuf; int msqid; if (msqid=msgget(999,0666)=-1) printf(Server is not runningn); exit(1); printf(Input a line:);scanf(%s,msgbuf.mtext); msgbuf.mtype=1;if (msgsnd(msqid,&msgbuf,256,0

14、)=-1)printf(error:msgsndn);exit(1);if (msgrcv(msqid,&msgbuf,256,2L,0)=-1)printf(error:msgrcvn);exit(1);printf(The reversed line is:%sn,msgbuf.mtext);exit(0);实验四 存储管理示例程序(注意阅读并分析可能存在的问题)#define TRUE 1#define FALSE 0#define INVALID -1#define null 0#define total_instruction 320/*指令流长*/#define total_vp

15、32/*虚页长*/#define clear_period 50/*清零周期*/typedef struct/*页面结构*/int pn,pfn,counter,time;pl_type;pl_type pltotal_vp;/*页面数组*/struct pfc_struct/*页面控制结构*/int pn,pfn;struct pfc_struct *next;typedef struct pfc_struct pfc_type;pfc_type pfctotal_vp,*freepf_head,*busypf_head,*busypf_tail;int diseffect,atotal_i

16、nstruction;int pagetotal_instruction, offsettotal_instruction;void initialize(int total_pf);void FIFO(int total_pf);void LRU(int total_pf);void OPT(int total_pf);void LFU(int total_pf);void NUR(int total_pf);#include #include #include main()int S,i;srand( (unsigned)time( NULL ) );/*srand(getpid()*10

17、);*/*由于每次运行时进程号不同,故可用来作为初始化随机数的种子*/S=(float)319*rand()/32767+1;for(i=0;itotal_instruction;i+=4)/*产生指令队列*/ai=S;/*任选一指令访问点*/ai+1=ai+1;/*顺序执行一条指令*/ai+2=(float)ai*rand()/32767;/*执行前地址指令m*/ai+3=ai+2+1;/*执行后地址指令*/S=(float)rand()*(318-ai+2)/32767+ai+2+2;for(i=0;itotal_instruction;i+)/*将指令序列变换成页地址流*/pagei=a

18、i/10;offseti=ai%10;for(i=4;i=32;i+)/*用户内存工作区从4个页面到32个页面*/printf(%2d page frames,i);FIFO(i);LRU(i);OPT(i);LFU(i);NUR(i);printf(n);return(0);/void FIFO(total_pf)/*FIFO(First In First Out) ALOGRITHM*/int total_pf;/*用户进程的内存页面数*/void FIFO(int total_pf)/int total_pf;int i;pfc_type *p;initialize(total_pf);

19、busypf_head=busypf_tail=NULL;for (i=0;inext;plbusypf_head-pn.pfn=INVALID;freepf_head=busypf_head;freepf_head-next=NULL;busypf_head=p;p=freepf_head-next;freepf_head-next=NULL;freepf_head-pn=pagei;plpagei.pfn=freepf_head-pfn;if (busypf_tail=NULL)busypf_head=busypf_tail=freepf_head;elsebusypf_tail-next

20、=freepf_head;busypf_tail=freepf_head;freepf_head=p;printf( FIFO:%6.4f,1-(float)diseffect/320);void LRU(int total_pf)/int total_pf;int min,minj,i,j,present_time;initialize(total_pf);present_time=0;for(i=0;itotal_instruction;i+)if (plpagei.pfn=INVALID)diseffect+;if (freepf_head=NULL)min=32767;for(j=0;

21、jplj.time & plj.pfn!=INVALID)min=plj.time;minj=j;freepf_head=&pfcplminj.pfn;plmin.pfn=INVALID;plmin.time=-1;freepf_head-next=NULL;plpagei.pfn=freepf_head-pfn;plpagei.time=present_time;freepf_head=freepf_head-next;elseplpagei.time=present_time;present_time+;printf( LRU:%6.4f,1-(float)diseffect/320);v

22、oid NUR(int total_pf)/int total_pf;int i,j,dp,cont_flag,old_dp;/pfc_type *t;initialize(total_pf);dp=0;for(i=0;itotal_instruction;i+)if (plpagei.pfn=INVALID)/*页面失效*/diseffect+;if (freepf_head=NULL)/*无空闲页面*/cont_flag=TRUE;old_dp=dp;while(cont_flag)if (pldp.counter=0&pldp.pfn!=INVALID)cont_flag=FALSE;e

23、lsedp+;if (dp=total_vp) dp=0;if (dp=old_dp)for (j=0;jnext=NULL;plpagei.pfn=freepf_head-pfn;freepf_head=freepf_head-next;elseplpagei.counter=1;if (i%clear_period=0)for(j=0;jtotal_vp;j+)plj.counter=0;printf( NUR:%6.4f,1-(float)diseffect/320);void OPT(int total_pf)/*OPT(Optional Replacement) ALOGRITHM*

24、/int total_pf;int i,j,max,maxpage,d,disttotal_vp;pfc_type *t;initialize(total_pf);for(i=0;itotal_instruction;i+)if (plpagei.pfn=INVALID)diseffect+;if (freepf_head=NULL)for(j=0;jtotal_vp;j+)if (plj.pfn!=INVALID)distj=32767;elsedistj=0;d=1;for(j=i+1;jtotal_instruction;j+)if (plpagej.pfn!=INVALID)distp

25、agej=d;d+;max=-1;for(j=0;jtotal_vp;j+)if (maxnext=NULL;plmaxpage.pfn=INVALID;plpagei.pfn=freepf_head-pfn;freepf_head=freepf_head-next;printf( OPT:%6.4f,1-(float)diseffect/320);void LFU(int total_pf)/*LFU(leat Frequently Used) ALOGRITHM*/int total_pf;int i,j,min,minpage;pfc_type *t;initialize(total_p

26、f);for(i=0;itotal_instruction;i+)if (plpagei.pfn=INVALID)diseffect+;if (freepf_head=NULL)min=32767;for(j=0;jplj.counter&plj.pfn!=INVALID)min=plj.counter;minpage=j;plj.counter=0;freepf_head=&pfcplminpage.pfn;plminpage.pfn=INVALID;freepf_head=freepf_head-next;elseplpagei.counter+;printf( LFU:%6.4f,1-(

27、float)diseffect/320);void initialize(int total_pf)/*初始化相关数据结构*/int total_pf;/*用户进程的内存页面数*/int i;diseffect=0;for(i=0;itotal_vp;i+)pli.pn=i;pli.pfn=INVALID;/*置页面控制结构中的页号,页面为空*/pli.counter=0;/*页面控制结构中的访问次数为0,时间为-1*/pli.time=-1;for(i=1;itotal_pf;i+)pfci-1.next=&pfci;pfci-1.pfn=i-1;/*建立pfci-1 和pfci之间的链接*

28、/pfctotal_pf-1.next=NULL;pfctotal_pf-1.pfn=total_pf-1;freepf_head=&pfc0;/*空页面队列的头指针为 pfc0*/实验五 设备管理一、实验步骤:LINUX中,模块可以用C语言编写,用gcc编译成目标文件(不进行链接,作为*.o文件存在),为此需要在gcc命令行里加上-c的参数。在编译时,还应该在gcc的命令行里加上这样的参数:-D_KERNEL_ -DMODULE。由于在不链接时,gcc只允许一个输入文件,因此一个模块的所有部分都必须在一个文件里实现。 如: gcc -D_KENERL_ -DMODULE -O2 -g -Wa

29、ll -c filename.c。1、编写用户设备驱动程序模块mychardev.c,编译该模块:#gcc -D_ _KERNEL_ _ -DMODULE -O2 -g -Wall -c mychardev.c2、加载设备驱动程序 mychardev.o:#insmod mychardev.o内核将提示主设备号及设备文件名的建立方法。如果有提示内核版不一致的错误,加上参数 f。可用lsmod检查新模块是否装入及系统中安装的模块的情况,要卸载该模块,用 rmmod 模块名 (不要扩展名.o)。3、建立设备文件节点(仅需一次)#cd /dev#mknod /dev/mychardev c 254

30、0其中mychardev是设备驱动程序中用register_chrdev()注册的设备名,c表示字符设备,数字254是主设备号,它是在设备驱动程序安装时提示的数据,也可以从文件/proc/devices中获取主设备号(这里是254)。对同一个物理设备,可以用同一主设备号建立多个不同的逻辑设备,也就是我们还可以用mknod /dev/mydev c 254 0命令建立另一个逻辑名为mydev的设备文件,通过该文件去使用相同的物理设备。删除该结点用命令 rm /dev/mychardev 。用ls命令查看/dev目录下的设备文件名的建立情况。也可查看/proc下proc文件系统记录的设备模块文件中

31、modules中有无加载的模块(用法 : #cat /proc/modules)。由于现在建立的是一个字符设备,因此可以用less 等命令查看文件的内容:less /dev/mydev。4、编制用户程序read_dev.c, 在用户进程中使用该设备(从设备中读取数据),反复运行,观察结果。5、修改设备驱动程序中的write()函数,实现对设备的写操作;同时修改用户程序,在用户程序中对设备进行读写。注意:设备驱动程序修改后,在重新装入前,应先把装入的驱动程序卸载。6、卸载设备驱动程序#rmmod mychardev二、示例程序:一个只读的字符设备。1、设备驱动程序mychardev.c/* my

32、chardev.c 创建一个只读的文件系统 */#ifndef MODULE#define MODULE#endif#include #include #include /* printk() */#include #include /* 字符设备所需*/#include #include /* 为兼容后续版本*/#include #include #include #include #include #include #include #define SUCCESS 0/* 设备定义 */* 设备名, 它将出现在 /proc/devices */#define DEVICE_NAME myc

33、hardev/* 该设备最大信息长度 */#define BUF_LEN 80/* 设备否打开?利用它防止当前进程使用同一设备*/static int Device_Open = 0;/* 提示信息 */char MessageBUF_LEN;/* 进程读取的信息的指针 */char *Message_Ptr;/* 当进程试图打开设备文件时调用该函数*/static int device_open(struct inode *inode, struct file *file) static int counter = 0;#ifdef DEBUG printk (device_open(%p,

34、%p)n, inode, file);#endif /* 两个进程不得同时对同一设备操作.*/ if (Device_Open) return -EBUSY; Device_Open+; /* 初始化信息. */ sprintf(Message, If I told you once, I told you %d times - Hello, world!n, counter+); /* 仅在输出信息的最大长度大于 BUF_LEN, (这儿是80)使用sprintf. * 注意不得超过缓冲区长度,尤其是在内核中! */ Message_Ptr = Message; /* 当文件打开时确信这个模

35、块存在.*/ MOD_INC_USE_COUNT; return SUCCESS;/* 当一个进程要关闭这个设备时,该函数被调用,这个调用不允许失败.*/static int device_release(struct inode *inode, struct file *file)#ifdef DEBUG printk (device_release(%p,%p)n, inode, file);#endif Device_Open -; /* 设备文件使用计数器减1*/ MOD_DEC_USE_COUNT;return 0;/* 当一进程要从已打开的设备文件读数据时该函数被调用.*/stat

36、ic ssize_t device_read(struct file *file, char *buffer, /* 获得填充数据的缓冲区*/ size_t length,loff_t *fops) /* 缓冲区中的数据长度 (绝对不能越界!) */ /* 已写入到缓冲区buffer中的确切字节数*/ int bytes_read = 0; char *ptr; int len=0;#ifdef DEBUG printk(device_read(%p,%p,%p,%d)n, inode, file, buffer, length);#endif /* 如果已位于信息尾部,返回0*/ if (*

37、Message_Ptr = 0) return 0; ptr=Message_Ptr; len=0 ; /*取字符串的长度*/ while (*(ptr+)len+; if (length80)len=80;elselen=length;copy_from_user(Message_Ptr,buffer,len); return -EINVAL;/* 模块定义 * */* 设备的主设备号*/static int Major;/* 当进程要对创建的设备进行某些操作时,这个结构存放了要调用的函数的入口* 这个结构有系统设备表的指针指向。NULL 表示未实现该功能。*/struct file_ope

38、rations Fops = read: device_read, write:device_write, open:device_open, release:device_release /* a.k.a. close */;/* 初始化模块-注册字符设备 */int init_module() /* 注册字符设备(至少一次) */ Major = register_chrdev(0, DEVICE_NAME, &Fops); /* 负值意味出错 */ if (Major 0) printk (Sorry, registering the character device failed wi

39、th %dn, Major); return Major; printk (Registeration is a success. The major device number is %d.n, Major); printk (If you want to talk to the device driver, youll have ton); printk (create a device file. We suggest you use:n); printk (mknod c %d 0n, Major); return 0;/* 清除模块 -从 /proc 中注销合适的文件*/void c

40、leanup_module() int ret; /* 注销设备 */ ret = unregister_chrdev(Major, DEVICE_NAME); /* 如果出错,报告错误*/ if (ret 0) printk(Error in module_unregister_chrdev: %dn, ret);/*在Redhat7.3以下版本请将其注释掉*/MODULE_LICENSE(GPL); 2、用户空间的读设备程序read_dev.c/*read_dev.c 使用用户设备驱动程序的示例*/#include #include main()int i,j,num;int f;char

41、 buffer80;f=open(/dev/mychardev,0);printf(How many chars do you read:(1-80);scanf(%d,&num);i=read(f,buffer,num);j=0;while (ji)printf(%c,bufferj);j+;close(f);printf(n);实验六 软盘I/O一、实验步骤整个实验需要一张MSDOS 格式的软盘,并且软盘上已经存放有一些文件。实验可按如下次序进行:1. 实现函数physicalDisk。2. 实现函数sectorRead 和segmentDump,可以得到任何给定扇区的16 进制输出。3.

42、 使用函数segmentDump 查看磁盘的内容。4. 编写程序调用physicalDisk、sectorRead 和segmentDump 三个函数,验证其正确性。二、磁盘读写示例程序1)Windows 98/NT环境下的磁盘读写 DiskIO_NT_98.cpp/ diskio.cpp : Defines the entry point for the console application./#include stdafx.h#include windows.h#include #include typedef struct _DIOC_REGISTERS DWORD reg_EBX; DWORD reg_EDX; DWORD reg_ECX; DWORD reg_EAX; DWORD reg_EDI; DWORD reg_ESI; DWORD reg_Flags; DIOC_REGISTERS ;#pragma pack(1)typedef struct _DISKIO

温馨提示

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

评论

0/150

提交评论