操作系统报告.docx
- 文档编号:4993918
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:24
- 大小:348.33KB
操作系统报告.docx
《操作系统报告.docx》由会员分享,可在线阅读,更多相关《操作系统报告.docx(24页珍藏版)》请在冰豆网上搜索。
操作系统报告
操作系统实验报告
姓名:
林大强
学号:
12070130
完成时间:
2014年11月22日
目录:
实验一:
UNIX/LINUIX入门…………………………………………………………………………………………..1
实验二:
进程管理……………………………………………………………………………………………………….3
实验三:
线程的管理…………………………………………………………………………………………………..10
实验四:
利用信号实现进程间通信…………………………………………………………………….……..15
实验五:
基于消息队列和共享内存的进程间通信……………………………………………….…...18
实验一UNIX/LINUIX入门
一、实验目的
了解UNIX/LINUX运行环境,熟悉UNIX/LINUX的常用基本命令,熟悉和掌握UNIX/LINUX下c语言程序的编写、编译、调试和运行方法。
二、实验内容
1、熟悉UNIX/LINUX的常用基本命令如ls、who、pwd、ps等。
2、练习UNIX/LINUX的文本行编辑器vi的使用方法
3、熟悉UNIX/LINUX下c语言编译器cc/gcc的使用方法。
用vi编写一个简单的显示“Hello,World!
”c语言程序,用gcc编译并观察编译后的结果,然后运行它。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。
四、实验设计
代码如下:
#include
voidmain(){
printf("helloworld");
}
五、运行结果
1
六、收获及机会
此次实验让我熟悉了Liunx下的文本行编辑器vi和c语言编译器cc/gcc的使用方法。
七、参考资料
《实验指导书》
2
实验二进程管理
一、实验目的
加深对进程概念的理解,明确进程与程序的区别;进一步认识并发执行的实质
二、实验内容
(1)进程创建
编写一段程序,使用系统调用fork()创建两个子进程。
当此程序运行时,在系统中有一
个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:
父进程显示“a“;子进
程分别显示字符”b“和字符“c”。
试观察记录屏幕上的显示结果,并分析原因。
(2)进程控制
修改已编写的程序,将每一个进程输出一个字符改为每一个进程输出一句话,再观察程
序执行时屏幕上出现的现象,并分析原因。
(3)进程的管道通信
编写程序实现进程的管道通信。
使用系统调用pipe()建立一个管道,二个子进程P1和
P2分别向管道各写一句话:
Child1issendingamessage!
Child2issendingamessage!
父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,再接收P2)。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,
并写出实验报告。
四、实验设计
(1)进程创建
使用fork()创建两个子进程,父进程等待两个子进程执行完在运行。
(2)进程控制
使用fork()创建两个子进程,父进程等待两个子进程分别输出一句话在运行。
(3)进程的管道通信
建立一个管道。
在程序中先建立一个子进程,然后向管道中输入数据,然后从子进程中退出到父进程,读出管道数据,然后再建立一个子进程,写入数据,再读出,即可。
代码如下:
(1)进程创建:
#include
#include
#include
#include
#include
#include
#defineINPUT0
#defineOUTPUT1
3
voidmain(){
pid_tpid[2];//定义两个子进程
pid[0]=fork();//创建第一个子进程
if(pid[0]<0){//判断是否创建成功
printf("ForkFailed");
exit(-1);
}
elseif(pid[0]==0)
{
printf("b\n");
}
else
{
pid[1]=fork();//创建另一子进程
if(pid[1]<0){
printf("ForkFailed");
exit(-1);
}
elseif(pid[1]==0)
{
printf("c\n");
}
else{
wait(NULL);
printf("a\n");//父进程执行
exit(0);
}
}
}
(2)进程控制:
#include
#include
#include
#include
#include
#include
4
#defineINPUT0
#defineOUTPUT1
voidmain(){
pid_tpid[2];
pid[0]=fork();
if(pid[0]<0){
printf("ForkFailed");
exit(-1);
}
elseif(pid[0]==0)
{
printf("thisisb\n");
}
else
{
pid[1]=fork();
if(pid[1]<0){
printf("ForkFailed");
exit(-1);
}
elseif(pid[1]==0)
{
printf("thisisc\n");
}
else{
wait(NULL);
printf("thisisa\n");
exit(0);
}
}
}
(3)进程的管道通信
5
#include
#include
#include
#include
#include
voidmain(){
intrw[2];
/*定义子进程号*/
pid_tpid[2];
intcount,count2;
/*创建无名管道*/
pipe(rw);
char*msg1="child1processissendingmessage!
\n";字符串msg1
char*msg2="child2processissendingmessage!
\n";字符串msg2
charbuf[50],s[50];
intresult;
result=pipe(rw);
if(result==-1){
printf("failedincallingpipe");
}
/*创建子进程*/
if((pid[0]=fork())==-1){
printf("Errorinfork\n");
exit
(1);
}
if(pid[0]==0){
//printf("child1processissendingmessage!
\n");
/*子进程向父进程写数据,关闭管道的读端*/
close(rw[0]);
write(rw[1],msg1,1+strlen(msg1));
close(rw[1]);
exit(0);
}
else{
if((pid[1]=fork())==-1){
printf("Errorinfork\n");
exit
(1);
}
if(pid[1]==0){
//printf("child2processissendingmessage!
\n");
/*子进程向父进程写数据,关闭管道的读端*/
6
close(rw[0]);
write(rw[1],msg2,1+strlen(msg2));
close(rw[1]);
exit(0);
}
else{
/*执行父进程*/
///printf("inthespawning(parent)process...\n");
/*父进程从管道读取子进程写的数据,关闭管道的写端*/
close(rw[1]);
count=read(rw[0],buf,sizeof(buf));
count2=read(rw[0],s,sizeof(s));
close(rw[0]);
printf("%d%s\n",count,buf);
printf("%d%s\n",count2,s);
}
}
}
五、运行结果
(1)进程创建
7
(2)进程控制
8
(3)进程的管道通信
六、收获及机会
此次实验让我对进程和管道有了进一步的理解,用fork()创建完子进程后,要用exit()返回父进程,当需要创建两个子进程的时候,不能直接在第一个子进程中直接fork(),要返回到父进程再用fork()再次创建子进程,否则将无法控制。
创建完管道后,在向管道中写入数据和从管道中读出数据的时候,要控制好管道的读写控制,不适当的关闭和开启管道端口,将不能使得数据得到正确的读写。
这些是我此次实验最大的收获,还需要在今后的时候发现更多的问题,有更深的理解。
七、参考资料
《实验指导书》
9
实验三线程的管理
一、实验目的
编写Linux环境下的多线程程序,了解多线程的程序设计方法,掌握最常用的三个函
数pthread_create,pthread_join和pthread_exit的用法
二、实验内容
1、主程序创建两个线程myThread1和myThread2,每个线程打印一句话。
使用pthread_create(&id,NULL,(void*)thread,NULL)完成。
提示:
先定义每个线程的执行体,然后在main中()创建几个线程,最后主线程等待子线程结
束后再退出。
2、创建两个线程,分别向线程传递如下两种类型的参数
传递整型值
传递字符
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,
并写出实验报告。
四、实验设计
先定义2个线程的带有参数的函数,参数分别为整型(int)和字符型(char),每个函数中打印出相对应线程的话。
在main函数中,利用pthread_create函数创建该两个线程,在函数参数中的第四位,写入想要传进各进程的参数。
最有利用pthread_join等待第二个结束后退出。
代码如下:
1、主程序创建两个线程myThread1和myThread2,每个线程打印一句话。
#include
#include
#include
#include
voidmyThread1(void)//线程1
{
printf("thisisphread1!
\n");
}
voidmyThread2(void)//线程2
{
printf("thisisphread2!
\n");
}
intmain(void)
10
{
pthread_tid[2];
intret;
ret=pthread_create(&id[0],NULL,(void*)myThread1,NULL);
if(ret!
=0){
printf("Createpthreaderror!
\n");
exit
(1);
}
ret=pthread_create(&id[1],NULL,(void*)myThread2,NULL);
if(ret!
=0){
printf("Createpthreaderror!
\n");
exit
(1);
}
pthread_join(id[0],NULL);
pthread_join(id[1],NULL);
printf("Thisisthemainprocess.\n");
return(0);
}
2、创建两个线程,分别向线程传递如下两种类型的参数
#include
#include
#include
#include
voidmyThread1(void*a)
{
int*num;
num=(int*)a;
printf("createintegeris%d\n",*num);
}
11
voidmyThread2(void*b)
{
char*x;
x=(char*)b;
printf("createcharis%c\n",*x);
}
intmain(void)
{
pthread_tid[2];
intret;
charc='L';
char*a=&c;
inttest=23;
int*attr=&test;
ret=pthread_create(&id[0],NULL,(void*)myThread1,(void*)attr);
if(ret!
=0){
printf("Createpthreaderror!
\n");
exit
(1);
}
pthread_join(id[0],NULL);
ret=pthread_create(&id[1],NULL,(void*)myThread2,(void*)a);
if(ret!
=0){
printf("Createpthreaderror!
\n");
exit
(1);
}
pthread_join(id[1],NULL);
printf("Thisisthemainprocess.\n");
return(0);
}
12
五、运行结果
1、主程序创建两个线程myThread1和myThread2,每个线程打印一句话。
2、创建两个线程,分别向线程传递如下两种类型的参数
13
六、收获及体会
此次实验让我对线程的创建有了进一步的理解,在熟练掌握pthread_create和pthread_join两个函数的应用上,进一步明白了如何向进程中传入参数。
七、参考资料
《实验指导书》
14
实验四利用信号实现进程间通信
一、实验目的
学习UNIX类操作系统信号机制,编写Linux环境下利用信号实现进程间通信的方法,掌握注册信号处理程序及signal()调用方法。
二、实验内容
编写一个程序,完成下列功能:
实现一个SIGINT信号的处理程序,注册该信号处理程序,创建一个子进程,父子进程都进入等待。
SIGINT信号的处理程序完成的任务包括打印接受到的信号的编号和进程PID。
编译并运行该程序,然后在键盘上敲Ctrl+C,观察出现
的现象,并解释。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,
并写出实验报告。
四、实验设计
创建一个进程,在父子进程中都注册一个用户敲中断键即Ctrl+C的信号处理程序,在子进程中注册一个用户定义信号1,在父进程中注册一个用户定义信号2,然后外部接收信号,最后在main函数中打印出信号的编号和进程PID。
在运行时,当用户键入Ctrl+C时,会自动打印出父子进程pid值,但信号的编号始终是父进程中注册的用户定义信号。
代码如下:
#include
#include
#include
#include
#defineMAXSTACK20
intstack[MAXSTACK];
inta=0;
intb=0;
sem_tsem,sem1;
voidReadData1(void){
FILE*fp=fopen("1.dat","r");
sem_wait(&sem1);
inti;
for(i=0;i<10;i++)
fscanf(fp,"%d",&stack[a++]);
sem_post(&sem1);
sem_post(&sem);
fclose(fp);
}
voidReadData2(void){
15
FILE*fp=fopen("2.dat","r");
sem_wait(&sem1);
inti;
for(i=0;i<8;i++)
fscanf(fp,"%d",&stack[a++]);
sem_post(&sem1);
sem_post(&sem);
fclose(fp);
}
voidHandleData1(void){
inti;
sem_wait(&sem);
for(i=0;i<4;i++){
intm=stack[b++];
intn=stack[b++];
printf("Plus:
%d+%d=%d\n",m,n,m+n);
}
}
voidHandleData2(void){
inti;
sem_wait(&sem);
for(i=0;i<4;i++){
intm=stack[b++];
intn=stack[b++];
printf("mul:
%d*%d=%d\n",m,n,m*n);
}
}
intmain(void){
pthread_tt1,t2,t3,t4;
sem_init(&sem,0,0);
sem_init(&sem1,0,1);
pthread_create(&t1,NULL,(void*)HandleData1,NULL);
pthread_create(&t2,NULL,(void*)HandleData2,NULL);
pthread_create(&t3,NULL,(void*)ReadData1,NULL);
pthread_create(&t4,NULL,(void*)ReadData2,NULL);
pthread_join(t1,NULL);
}
16
五、运行结果
六、收获及体会
此次实验让我学会了在Linux环境下利用信号实现进程间通信的方法,掌握注册信号处理程序及signal()调用方法,也掌握了接收信号的写法。
并在试验中,可通过用户自己输入信号来产生信号的编号,但是通过注册SIGINT信号处理程序打印出的信号编号只是父进程中创建的用户定义信号2,这点还是需要进一步讨论。
但总的来说,对利用信号实现进程间的通信,有了更深入的一个了解,收获很大。
七、参考资料
《实验指导书》
17
实验五基于消息队列和共享内存的进程间通信
一、实验目的
Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据。
本实验的目的是了解和熟悉:
1.Linux支持的消息通信机制及其使用方法
2.Linux系统的共享存储区的原理及使用方法。
二、实验内容
1.消息的创建、发送和接收
使用消息调用msgget()、msgsnd()、msggrev()、msgctrl()编制长度为1K的消息的发送和接收程序。
2.共享存储区的创建、附接和断接
使用系统调用shmget()、shmat()、shmctl(),编制一个与上述功能相同的程序。
三、实验要求
按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,
并写出实验报告。
四、实验设计
1.消息队列:
先定义一个消息结构,包含消息类型和文本长度。
在SERVER函数中,首先获得一个KEY为75的消息的描述符,然后利用dowhile循环来判断当消息类型为1的时候打印输出。
在CLIENT函数中,先获得消息队列,然后利用for循环将消息类型从10赋值到1,发送队列,并打印输出。
最后在main函数中调用这两个函数。
#include
#include
#include
#include
#defineMSGKEY75
structmsgform/*消息结构*/
{
longmtype;/*消息类型*/
charmtexe[1030];/*文本长度*/
}msg;
intmsgqid,i;
voidCLIENT()
{
inti;
msgqid=msgget(MSGKEY,0777);/*获得消息的描述符msgqid*/
for(i=10;i>=1;i--)/*将消息类型由10到1发送*/
{
msg.mtype=i;
18
printf("(client)sent\n");
msgsnd(msgqid,&msg,1024,0);/*发送消息msg入msgid消息队列*/
}
exit(0);
}
voidSERVER()
{
msgqid=msgget(MSGKEY,0777|IPC_CREAT);
do
{
msgrcv(msgqid,&msg,1030,0,0);/*从队列msgid接受消息msg*/
printf("(server)receive\n");
}while(msg.mtype!
=1);/*消息类型为1时,释放队列*/
msgctl(msgqid,IPC_RMID,0);
exit(0);
}
main()
{
if(fork())SERVER();
elseCLIENT();
wait(0);
wait(0);
}
2.共享存储区:
先获取共享区,KEY为75,并获得描述符,然后将该共享存储区附接到addr这个虚拟地址上,如消息队列类似,利用while循环从10到1打印输出,并将i值赋给addr。
在SERVER中,创建共享存储区,并将起始地址也设置为addr,服务进程共享存储区,所以直接用while循环输出打印“receive”。
代码如下:
#include
#include
#include
#d
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 报告