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

下载本文档

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

文档简介

1、精选优质文档-倾情为你奉上操作系统实验报告 学 号: 姓 名: 指导老师: 完成日期: 目录实验一1实验二2实验三7实验四10实验五15实验六18实验七22专心-专注-专业实验一 UNIX/LINUX入门一、实验目的了解 UNIX/LINUX 运行环境,熟悉UNIX/LINUX 的常用基本命令,熟悉和掌握UNIX/LINUX 下c 语言程序的编写、编译、调试和运行方法。二、实验内容 熟悉 UNIX/LINUX 的常用基本命令如ls、who、pwd、ps 等。练习 UNIX/LINUX的文本行编辑器vi 的使用方法熟悉 UNIX/LINUX 下c 语言编译器cc/gcc 的使用方法。用vi 编写

2、一个简单的显示“Hello,World!”c 语言程序,用gcc 编译并观察编译后的结果,然后运行它。三、实验要求按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。四、实验程序#include <stdio.h> #include <stdlib.h> int main() printf ("Hello World!n"); return 0;五、实验感想通过第一次室验,我了解 UNIX/LINUX 运行环境,熟悉了UNIX/LINUX 的常用基本命令,熟悉和掌握了UNIX/LINUX 下c 语言程序的编写、

3、编译、调试和运行方法。实验二 进程管理一、实验目的加深对进程概念的理解,明确进程与程序的区别;进一步认识并发执行的实质。二、实验内容(1)进程创建编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示“a“;子进程分别显示字符”b“和字符“c”。试观察记录屏幕上的显示结果,并分析原因。(2)进程控制修改已编写的程序,将每一个进程输出一个字符改为每一个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。(3)进程的管道通信编写程序实现进程的管道通信。使用系统调用pipe()建立一个管道,二

4、个子进程P1 和P2 分别向管道各写一句话:Child 1 is sending a message!Child 2 is sending a message!父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,再接收P2)。三、实验要求按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。四、实验设计 1、功能设计(1)进程创建使用fork()创建两个子进程,父进程等待两个子进程执行完再运行。(2)进程控制使用fork()创建两个子进程,父进程等待两个子进程分别输出一句话再运行。(3)进程的管道通信 先创建子进程1,向管道写入一句话,子进程1结

5、束后创建子进程2,向管道写入一句话,最后父进程从管道中读出。 2、数据结构 子进程和管道。 3、程序框图 五、实验程序(1)进程创建#include<stdio.h>#include<stdlib.h>int main() int pid1, pid2;pid1=fork();if (pid1<0) printf("Fork 1 failed!");if (pid1=0) printf("bn");exit(0); if (pid1>0) wait(NULL);pid2 = fork(); if (pid2<0)

6、 printf("Fork 2 failed!"); if (pid2=0) printf("cn");exit(0); if (pid2>0) wait(NULL);printf("an");exit(0); (2)进程控制#include<stdio.h>#include<stdlib.h>int main() int pid1, pid2;pid1=fork();if (pid1<0) printf("Fork 1 failed!");if (pid1=0) printf(

7、"This is child bn");exit(0); if (pid1>0) wait(NULL);pid2 = fork(); if (pid2<0) printf("Fork 2 failed!"); if (pid2=0) printf("This is child cn"); exit(0); if (pid2>0) wait(NULL); printf("This is father an"); exit(0); (3)进程的管道通信#include<stdio.h>#i

8、nclude<stdlib.h>#include<sys/types.h>#include<memory.h>int main() int pid1, pid2; int pfd2;char *msg1="Child 1 is sending a message!"char *msg2="Child 2 is sending a message!" char buf256; int r,w; if(pipe(pfd)<0) printf("pipe create error!n"); exit

9、(1);pid1 = fork();if (pid1<0) printf("Fork 1 failed!"); if (pid1=0) close(pfd0); /writesleep(3);if(w=write(pfd1,msg1,strlen(msg1)<0) printf("wirte error!n");exit(1);else printf("child 1 send msg to pipe!n"); exit(0);if(pid1>0) wait(NULL);pid2 = fork(); if(pid2&

10、lt;0) printf("Fork 2 failed!"); if(pid2>0) close(pfd1); /read sleep(3); if(r=read(pfd0,buf,256)<0) printf("read error!n");exit(1); else printf("parent read from pipe: %sn",buf); wait(NULL); close(pfd1); /read sleep(3); if(r=read(pfd0,buf,256)<0) printf("re

11、ad error!n");exit(1); else printf("parent read from pipe: %sn",buf); if(pid2=0) close(pfd0); /write sleep(6); if(w=write(pfd1,msg2,strlen(msg2)<0) printf("write error!n");exit(1); else printf("child 2 send msg to pipe!n"); exit(0); 六、实验结果从图中可以看出,分别输出了,三个字母,三句话,实

12、现了子进程向管道写数据,父进程从管道中读出。七、实验感想通过本次实验,我们对进程的概念加深了理解,熟悉了进程的创建方法与作用机制,明确了进程与程序的异同。同时,我们掌握了使用管道通信的机制,进一步认识了并发执行的实质。实验三 一个进程启动另一个程序的执行一、实验目的编写 Linux 环境下,fork()与exec()的结合使用实现一个进程启动另一个程序的执行的基本方法,掌握exec()的几种调用方法。二、实验内容父进程从终端读取要执行的命令,并交给子进程执行。父进程等待子进程结束,并打印子进程的返回值。三、实验要求按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写

13、出实验报告。四、实验设计1、功能设计根据实验要求,父进程和子进程将被分配不同的任务:父进程从终端读取要执行的命令交给子进程,然后等待子进程技术打印子进程的返回值;子进程执行父进程读取的命令并返回给父进程。因为子进程执行命令需要打开其他文件,所以需要使用exec()类的函数实现在一个进程来启动另一个程序,在这里应使用execlp()函数从PATH环境变量中查找文件并执行。对于父进程,可以调用fget()从终端读取要执行的命令,以字符串形式存储然后交给子进程执行,待子进程执行完毕后接收子进程返回值并打印。由于要求带参数的命令也可以执行,那么需要在父进程中fets两次,第一次gets得到命令给串co

14、mmand,然后gets参数给串command1,并且将这两个参数分别传到子进程的exec()函数,其中前两个都是command,第三个是command1。2、数据结构用char*型全局变量command存放指令用char*型全局变量command1存放参数3、程序框图五、实验程序#include <stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>char command256;char command1256;int main()int rtn; /子进程的返回数值in

15、t errorno;while(1) printf( ">" ); /从终端读取要执行的命令fgets( command, 256, stdin );printf( "<" ); /从终端读取要执行命令的参数fgets( command1, 256, stdin );commandstrlen(command)-1 = '0'command1strlen(command1)-1 = '0'if ( fork() = 0 ) /子进程执行此命令errorno=(command10=0)?:execlp(comma

16、nd, command, NULL, NULL), execlp(command, command, command1, NULL);/如果没有参数则前者的execlp()函数,如果有参数则执行后者,有无参数只需看command10是否为0perror( command ); /如果exec函数返回,表明没有正常执行命令,打印错误信息exit(errorno);else /父进程, 等待子进程结束,并打印子进程的返回值wait ( &rtn );printf( " child process return %dn", rtn );return 0;六、实验结果由图可

17、知,执行了ls命令,参数为-a,文件按字母顺序显示如上图所示,输入命令ls,输入参数-a,输出文件夹的内容。七、实验感想通过本次实验,我学会了如何用execlp()函数达到一个进程启动另外一个程序的目的。并且对execlp()的几个参数的作用有了一定了解,别且对于fork()和exelp()联合使用的方法和功能。同时,我们进一步熟悉了LINUX系统操作环境,学习了在LINUX环境下编译和调试程序的技巧。实验四 基于消息队列和共享内存的进程间通信一、实验目的Linux 系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据。本实验的目的是了解和熟悉:1. Linux 支持的消息通信机制及其

18、使用方法2. Linux 系统的共享存储区的原理及使用方法。二、实验内容1消息的创建、发送和接收使用消息调用 msgget()、msgsnd()、msggrev()、msgctrl()编制长度为1K 的消息的发送和接收程序。2共享存储取得创建、附接和断接使用系统调用 shmget()、shmat()、shmctl()、shmctl(),编制一个与上述功能相同的程序。三、实验要求按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。四、实验设计1、消息的创建、发送和接收(1)功能设计为了实现进程之间消息的创建、发送和接收,首先应定义两个子进程,Server进

19、程负责发送,Client进程负责接收,父进程负责创建。其次需要用到msgget()、msgsnd()、msggrev()、msgctrl()等函数进行对消息的控制。题目要求消息长度为1K,那么msgsnd(id,msgp,size, flag)和msgrcv(id,msgp,size,type,flag)函数中参数size应设为1024,msgget(key,flag)中的key应为75。父进程获得创建消息后,子进程Server先后发送编号为110的10条消息,子进程Client先后接收这10条消息,方能达到实验目的。(2)数据结构消息(mymsg):结构体实现,包含的成员变量有消息类型和消息

20、内容,具体实现如下:struct mymsg/消息的结构体声明long int mymsgtype;/消息类型int text;/消息内容(3)程序框图2、共享存储区的创建、附接和断接(1)功能设计为了实现进程通过共享存储区进行通信,需要创建两个进程并且调用shmget()、shmat()、shmctl()函数实现共享存储区的创建、附接和断接。由于共享存储区的写入和读取由两个子进程完成,而共享存储区在本程序中为所有进程共用的,因此共享存储区的创建、附接和断接均需要在父进程中完成。具体的实现方式是现在父进程中创建一块共享存储区,然后用int类型指针list指向该存储区的地址;接着创建两个子进程,

21、第一个子进程通过list指针实现向共享存储区写入int类型的数据,第二个子进程通过list指针实现从共享存储区读出int类型的数据。由于两个子进程同时使用了list指针,所以需要控制两个进程互斥,在读进程序中添加了sleep(1)语句。(2)数据结构通过shmid=shmget (key ,size ,flag)函数建立(获得)共享存储区,返回该共享存储区的描述符shmid。(3)程序框图五、实验程序1、消息的创建、发送和接收#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<

22、;sys/ipc.h>#include<sys/msg.h>#include<sys/shm.h>#define MAX 1024#define KEY 75struct mymsg/消息结构体long int mymsgtype;/消息类型int text;/消息内容msg;int main()pid_t pids; pid_t pidc; int msgid; int i=1;msgid=msgget(KEY,0666|IPC_CREAT);/获得一个消息的描述符if(pids=fork()=0)/创建Server子进程while(i<11)msg.my

23、msgtype=11-i;msg.text=i;printf("the sended message is %d thn",i); i+; msgsnd(msgid,&msg,MAX,0); /向msgid指定的消息队列发送消息,长度为1K exit(0); else i=10;if(pidc=fork()=0) /创建Client子进程while(i!=1)msgrcv(msgid,&msg,MAX,0,0); /从msgid指定的消息队列接收消息printf("the message is %d thn",msg.text);i=ms

24、g.mymsgtype;exit(0);elsewait(0); wait(0); exit(0); 2、共享存储区的创建、附接和断接#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#define MAX 11#define KEY 75main()int i,child1,child2,running

25、=1;/定义子进程号int id; int *list;id=shmget(KEY,sizeof(int)*MAX,IPC_CREAT|0666); /建立一块共享存储区,返回该共享存储区的描述符idlist=(int*)shmat(id,0,0); /将list指针指向共享存储区if(child1=fork()=-1)printf("error in fork an"); exit(1); if(child1=0) sleep(1); for(i=0;i<=10;i+)printf("your message is: %d n",listi);

26、exit(0); elseif(child2=fork()=-1)printf("error in fork an");exit(1); if(child2=0)i=0;while(1)listi=i; /向缓冲区里写入数据printf("the message sent is : %dn",listi);if(listi=10) break; i+;exit(0);elsewait(0); wait(0); shmdt(list); /将共享存储区与进城断开shmctl(id,IPC_RMID,0);/ 将共享存储区标志为被销毁的exit(0); 六、

27、实验结果(1)消息的创建、发送和接收 第一个子进程一次发了10条消息,第二个子进程一次接收了10条消息,消息队列先进先出。(2)共享存储区的创建、附接和断接第一个子进程向共享存储区写入了11个数据,第二个子进程从共享存储区读取,两个进程之间是互斥执行的。七、实验感想通过本次实验,我学会了如何用消息队列和共享内存的方式实现进程间的通信,掌握了Linux系统的消息通信机制和共享存储区的原理,并在实践过程中掌握了它们的使用方法。在编程和调试的过程中,我进一步熟悉了LINUX环境下的编译过程和调试方法。实验五 利用信号实现进程间通信一、实验目的学习 UNIX 类操作系统信号机制,编写Linux 环境下

28、利用信号实现进程间通信的方法,掌握注册信号处理程序及signal()调用方法。二、实验内容编写一个程序,完成下列功能:实现一个SIGINT 信号的处理程序,注册该信号处理程序,创建一个子进程,父子进程都进入等待。SIGINT 信号的处理程序完成的任务包括打印接受到的信号的编号和进程PID。编译并运行该程序,然后在键盘上敲Ctrl + C,观察出现的现象,并解释。提示:参见“五、补充材料”中的signal()的基本用法。三、实验要求按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。四、实验设计1、功能设计本实验要求利用信号实现进程间通信。为了实现实验目的

29、,需要实现一个SIGINT信号的处理函数func()并注册该信号处理函数。信号处理函数需要完成的任务应包括打印接受到的信号的编号和进程的PID,所以func()函数应能实现打印当前进程的pid以及根据接收到的信号的编号打印出该信号名称的功能。父进程和子进程分别接收两个不同的信号,因此两个进程调用signal()函数时应为不同的信号注册信号处理函数。本次实验采用了SIGINT和SIGUSR1两个信号。为了让父子进程都能够接收到信号,在注册信号处理函数后应让两个进程进入等待,并且为了方便验证试验结果,让父进程接收SIGINT信号,子进程接收SIGUSR1信号。2、数据结构信号(SIGNAL):UN

30、IX系统含有20种信号。可以使用signal()函数为每个信号注册信号处理函数。3、程序框图五、实验程序#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<unistd.h>void func(int i);int pid;int main()if(pid=fork()=0)/创建子进程printf("sonpid:%dn",pid);/ 打印子进程号signal(SIGUSR1,func);/ 注册SIGUSR1的信号处理程序for ( ; ; )/子进

31、程进入等待pause();elseprintf("fatherpid:%dn",pid);/ 打印父进程号signal(SIGINT,func);/注册SIGINT的信号处理程序for ( ; ; )/父进程进入等待pause();void func(int i)/ 信号处理函数printf("pid:%dn",pid);if (i = SIGUSR1)printf("received SIGUSR1n");else if (i = SIGUSR2)printf("received SIGUSR2n");else

32、if(i = SIGINT)printf("received SIGINT %dn", i);exit(1);exit(0);六、实验结果如图所示,第一次执行后打印父进程和子进程pid,按ctrl+c后,父进程接收信号,信号处理程序输出父进程号2472和信号名称。第二次使用./shiyan5&后台运行此程序,使用kill USR1 2472时,子进程接收信号,信号处理程序输出子进程号0,并输出信号名称。七、实验心得通过本次实验,我掌握了注册信号处理程序及signal()调用方法,并且了解了如何让程序在后台运行的方法。我也进一步了解了LINUX系统中进程同步与通信的原

33、理。 实验六 线程的创建一、实验目的编写 Linux 环境下的多线程程序,了解多线程的程序设计方法,掌握最常用的三个函数pthread_create,pthread_join 和pthread_exit 的用法。二、实验内容1、主程序创建两个线程 myThread1 和myThread2 ,每个线程打印一句话。使用pthread_create(&id,NULL,(void *) thread,NULL)完成。2、创建两个线程,分别向线程传递如下两种类型的参数传递整型值传递字符三、实验要求按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。四、实验

34、设计1、创建两个进程每个进程打印一句话(1)功能设计题目要求创建两个线程,每个线程打印一句话,可以认为两个线程的功能是相同的,故只需要写一个线程的运行函数thread(),在这个函数里有一个printf输出一句话即可。然后在main函数里分别创建两个线程,然后等待两个线程结束。(2)数据结构线程:使用pthread_create()创建。每个线程有相应的线程标示符,也有各自的属性。线程可以和线程运行函数绑定,并可以在创建线程时确定该线程运行函数的参数。(3)程序框图2、创建两个进程每个进程打印一句话分别向线程传递如下两种类型的参数 :整型值、字符(1)功能设计题目要求创建两个线程,两个线程分别

35、传递int型和char型数据给线程运行函数。所以要编写两个不同的线程运行函数分别接收int型和char型的数据。相应的pthread_create()函数中要给第四个参数,作为形参传进线程运行函数。(2)数据结构线程:同1,使用pthread_create()创建。每个线程有相应的线程标示符,也有各自的属性。线程可以和线程运行函数绑定,并可以在创建线程时确定该线程运行函数的参数。(3)程序框图五、实验程序1、创建两个进程每个进程打印一句话#include <stdio.h>#include<stdlib.h>#include <pthread.h>void

36、thread()/线程运行函数printf("This is a pthread.n");/输出一句话int main()pthread_t id1,id2;/定义两个线程标识符int i,ret; ret=pthread_create(&id1,NULL,(void *) thread,NULL);/创建线程标识为id1 if(ret!=0)/线程创建失败 printf ("Create pthread error!n");exit (1); ret=pthread_create(&id2,NULL,(void *) thread,NU

37、LL); /创建线程标识为id2 if(ret!=0) /线程创建失败printf ("Create pthread error!n");exit (1);printf("This is the main process.n");pthread_join(id1,NULL);/等待第一个线程结束pthread_join(id2,NULL);/等待第二个线程结束return (0);2、创建两个进程每个进程打印一句话分别向线程传递如下两种类型的参数 :整型值、字符#include <pthread.h>#include <stdio.h&

38、gt;#include <stdlib.h>#include <unistd.h>void threadchar(char * c)/接收字符的线程运行函数 printf("receive a char:%cn",c);void threadint(int * i)/接收整数的线程运行函数printf("receive a int:%dn",i);int main(void) pthread_t id1,id2; int ret; char c='t' char *a=c;/定义char*指针变量传参数用 ret=

39、pthread_create(&id1,NULL,(void *) threadchar,a);/创建线程1,第四个参数为char*型变量用来传递字符 if(ret!=0)/线程创建失败 printf ("Create pthread error!n"); exit (1); int i=99; int *b=i; /定义int*指针变量传参数用 ret=pthread_create(&id2,NULL,(void *) threadint,b);/创建线程2,第四个参数为int*型变量用来传递字符 if(ret!=0) /线程创建失败 printf (&q

40、uot;Create pthread error!n"); exit (1); printf("This is the main process.n"); pthread_join(id1,NULL); /等待线程1结束 pthread_join(id2,NULL); /等待线程2结束 return (0);六、实验结果由图可知两个线程主程序创建了两个进程这两个进程分别输出了一句话。主程序分别创建了两个线程并向线程1传递了t向线程2传递了99,线程运行函数分别输出告知接收了这两个参数。七、实验感想通过本次实验,我学会了如何使用LINUX下的线程创建函数pthrea

41、d_create()来创建线程,并且向线程传递参数。同时更加熟练的使用LINUX。实验七 利用信号量实现进程的控制一、实验目的学习 UNIX 类操作系统信号量机制,编写Linux 环境下利用信号量实现进程控制的方法,掌握相关系统调用的使用方法。二、实验内容创建4 个线程,其中两个线程负责从文件读取数据到公共的缓冲区,另两个线程从缓冲区读取数据作不同的处理(加和乘运算)。使用信号量控制这些线程的执行。三、实验要求按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。四、实验设计1、功能设计题目要求创建4个线程,其中两个负责从文件读数据到缓冲区,另两个负责从缓

42、冲区读数据进行加和乘的运算。我对这4个线程进行如下安排,线程1读后线程2才可以读,线程2读了后线程3才可以进行加的运算,线程3加完了后线程4才能进行乘的运算,线程4乘完后线程1才能继续读。故需4个信号量sem1,sem2,sem3,sem4。线程1消费sem1生产sem2,线程2消费sem2生产sem3,线程3消费sem3生产sem4,线程4消费sem4生产sem1,形成一个循环,直到文件结束为止。2、数据结构信号量(semaphore):数据类型为结构 sem_t,本质上是一个长整型的数。一共4个公共缓冲区(stack):采用2维数组的方式实现(stackNUM2)。数组中的两列分别存储两个文件中的数据。该2维数组还有一个索引:size,指向2维数组的顶部。读线程每

温馨提示

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

评论

0/150

提交评论