操作系统实验报告.docx
《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(19页珍藏版)》请在冰豆网上搜索。
操作系统实验报告
操作系统实验报告
'
学号:
姓名:
指导老师:
完成日期:
~
实验一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编写一个简单的显示“Hello,World!
”c语言程序,用gcc编译并观察编译后的结果,然后运行它。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。
四、实验程序
#include<>
#include<>
intmain()
{
printf("HelloWorld!
\n");
return0;
}
五、实验感想
通过第一次室验,我了解UNIX/LINUX运行环境,熟悉了UNIX/LINUX的常用基本命令,熟悉和掌握了UNIX/LINUX下c语言程序的编写、编译、调试和运行方法。
实验二进程管理
一、实验目的
加深对进程概念的理解,明确进程与程序的区别;进一步认识并发执行的实质。
二、实验内容
(1)进程创建
编写一段程序,使用系统调用fork()创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:
父进程显示“a“;子进程分别显示字符”b“和字符“c”。
试观察记录屏幕上的显示结果,并分析原因。
(2)进程控制
修改已编写的程序,将每一个进程输出一个字符改为每一个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。
(3)进程的管道通信
编写程序实现进程的管道通信。
使用系统调用pipe()建立一个管道,二个子进程P1和P2分别向管道各写一句话:
Child1issendingamessage!
Child2issendingamessage!
父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,再接收P2)。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。
四、实验设计
1、功能设计
(1)进程创建
使用fork()创建两个子进程,父进程等待两个子进程执行完再运行。
(2)进程控制
使用fork()创建两个子进程,父进程等待两个子进程分别输出一句话再运行。
(3)进程的管道通信
先创建子进程1,向管道写入一句话,子进程1结束后创建子进程2,向管道写入一句话,最后父进程从管道中读出。
2、数据结构
子进程和管道。
3、程序框图
五、实验程序
(1)进程创建
#include<>
#include<>
intmain()
{
intpid1,pid2;
pid1=fork();
if(pid1<0){printf("Fork1failed!
!
");}
if(pid1==0){printf("b\n");exit(0);}
if(pid1>0){wait(NULL);
pid2=fork();
if(pid2<0){printf("Fork2failed!
!
");}
if(pid2==0){printf("c\n");exit(0);}
if(pid2>0){wait(NULL);printf("a\n");exit(0);}
}
}
(2)进程控制
#include<>
#include<>
intmain()
{
intpid1,pid2;
pid1=fork();
if(pid1<0){printf("Fork1failed!
!
");}
if(pid1==0){printf("Thisischildb\n");exit(0);}
if(pid1>0){wait(NULL);
pid2=fork();
if(pid2<0){printf("Fork2failed!
!
");}
if(pid2==0){printf("Thisischildc\n");
exit(0);}
if(pid2>0){wait(NULL);
printf("Thisisfathera\n");
exit(0);}
}
}
(3)进程的管道通信
#include<>
#include<>
#include
#include<>
intmain()
{
intpid1,pid2;intpfd[2];
char*msg1="Child1issendingamessage!
";
char*msg2="Child2issendingamessage!
";
charbuf[256];intr,w;
if(pipe(pfd)<0){printf("pipecreateerror!
\n");exit
(1);}
pid1=fork();
if(pid1<0){printf("Fork1failed!
!
");}
if(pid1==0){close(pfd[0]);Linux支持的消息通信机制及其使用方法
2.Linux系统的共享存储区的原理及使用方法。
二、实验内容
1.消息的创建、发送和接收
使用消息调用msgget()、msgsnd()、msggrev()、msgctrl()编制长度为1K的消息的发送和接收程序。
2.共享存储取得创建、附接和断接
使用系统调用shmget()、shmat()、shmctl()、shmctl(),编制一个与上述功能相同的程序。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。
四、实验设计
1、消息的创建、发送和接收
(1)功能设计
为了实现进程之间消息的创建、发送和接收,首先应定义两个子进程,Server进程负责发送,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先后发送编号为1~10的10条消息,子进程Client先后接收这10条消息,方能达到实验目的。
(2)数据结构
消息(mymsg):
结构体实现,包含的成员变量有消息类型和消息内容,具体实现如下:
structmymsg{
shiyan5&后台运行此程序,使用kill–USR12472时,子进程接收信号,信号处理程序输出子进程号0,并输出信号名称。
七、实验心得
通过本次实验,我掌握了注册信号处理程序及signal()调用方法,并且了解了如何让程序在后台运行的方法。
我也进一步了解了LINUX系统中进程同步与通信的原理。
实验六线程的创建
一、实验目的
编写Linux环境下的多线程程序,了解多线程的程序设计方法,掌握最常用的三个函数pthread_create,pthread_join和pthread_exit的用法。
二、实验内容
1、主程序创建两个线程myThread1和myThread2,每个线程打印一句话。
使用pthread_create(&id,NULL,(void*)thread,NULL)完成。
2、创建两个线程,分别向线程传递如下两种类型的参数
传递整型值
传递字符
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。
四、实验设计
1、创建两个进程每个进程打印一句话
(1)功能设计
题目要求创建两个线程,每个线程打印一句话,可以认为两个线程的功能是相同的,故只需要写一个线程的运行函数thread(),在这个函数里有一个printf输出一句话即可。
然后在main函数里分别创建两个线程,然后等待两个线程结束。
(2)数据结构
线程:
使用pthread_create()创建。
每个线程有相应的线程标示符,也有各自的属性。
线程可以和线程运行函数绑定,并可以在创建线程时确定该线程运行函数的参数。
(3)程序框图
2、创建两个进程每个进程打印一句话分别向线程传递如下两种类型的参数:
整型值、字符
(1)功能设计
题目要求创建两个线程,两个线程分别传递int型和char型数据给线程运行函数。
所以要编写两个不同的线程运行函数分别接收int型和char型的数据。
相应的pthread_create()函数中要给第四个参数,作为形参传进线程运行函数。
(2)数据结构
线程:
同1,使用pthread_create()创建。
每个线程有相应的线程标示符,也有各自的属性。
线程可以和线程运行函数绑定,并可以在创建线程时确定该线程运行函数的参数。
(3)程序框图
五、实验程序
1、创建两个进程每个进程打印一句话
#include<>
#include<>
#include<>
voidthread()n");n");
pthread_join(id1,NULL);n");
pthread_join(id1,NULL);//等待线程1结束
pthread_join(id2,NULL);//等待线程2结束
return(0);
}
六、实验结果
由图可知两个线程主程序创建了两个进程这两个进程分别输出了一句话。
主程序分别创建了两个线程并向线程1传递了‘t’向线程2传递了99,线程运行函数分别输出告知接收了这两个参数。
七、实验感想
通过本次实验,我学会了如何使用LINUX下的线程创建函数pthread_create()来创建线程,并且向线程传递参数。
同时更加熟练的使用LINUX。
实验七利用信号量实现进程的控制
一、实验目的
学习UNIX类操作系统信号量机制,编写Linux环境下利用信号量实现进程控制的方法,掌握相关系统调用的使用方法。
二、实验内容
创建4个线程,其中两个线程负责从文件读取数据到公共的缓冲区,另两个线程从缓冲区读取数据作不同的处理(加和乘运算)。
使用信号量控制这些线程的执行。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。
四、实验设计
1、功能设计
题目要求创建4个线程,其中两个负责从文件读数据到缓冲区,另两个负责从缓冲区读数据进行加和乘的运算。
我对这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维数组的方式实现(stack[NUM][2])。
数组中的两列分别存储两个文件中的数据。
该2维数组还有一个索引:
size,指向2维数组的顶部。
读线程每次从文件读出两个数放到stack[NUM][0]和stack[NUM][1]
3、程序框图
五、实验程序
#include<>
#include<>
#include<>
#defineMAX10
intoperand[MAX][2];
intsize=0;
sem_tsem;
voidReadData1(void){
FILE*fp=fopen("","r");
while(!
feof(fp)){
fscanf(fp,"%d%d",&operand[size][0],&operand[size][1]);
if(feof(fp))break;++size;
sem_post(&sem);
}
fclose(fp);
}
voidReadData2(void){
FILE*fp=fopen("","r");
while(!
feof(fp)){
fscanf(fp,"%d%d",&operand[size][0],&operand[size][1]);
if(feof(fp))break;++size;
sem_post(&sem);
}
fclose(fp);
}
voidHandleData1(void){
while
(1){
sem_wait(&sem);
--size;
printf("Plus:
%d+%d=%d\n",operand[size][0],operand[size][1],
operand[size][0]+operand[size][1]);
}
}
voidHandleData2(void){
while
(1){
sem_wait(&sem);
--size;
printf("Multiply:
%d*%d=%d\n",operand[size][0],operand[size][1],
operand[size][0]*operand[size][1]);
}
}
intmain(void)
{
pthread_tt1,t2,t3,t4;
sem_init(&sem,0,0);
pthread_create(&t3,NULL,(void*)ReadData1,NULL);
pthread_create(&t1,NULL,(void*)HandleData1,NULL);
pthread_create(&t4,NULL,(void*)ReadData2,NULL);
pthread_create(&t2,NULL,(void*)HandleData2,NULL);
pthread_join(t2,NULL);
return0;
}
六、实验结果
从图可知线程1从读两个数到缓冲区然后线程2从读两个数到缓冲区,然后线程3从缓冲区读出两个数相加,最后线程4再读出两个数相乘。
七、实验感想
通过本次实验,我进一步掌握了如何使用LINUX下的线程创建函数pthread_create()创建线程,并且学会了如何使用信号量控制进程的运行,学会了使用消费函数sem_wait(),生产函数sem_post(),以及如何初始化信号量,同时也掌握了文件的读取方法,本次实验加深了我对信号量的认识。
】