计算机操作系统实验报告Word文档格式.docx

上传人:b****5 文档编号:17027327 上传时间:2022-11-27 格式:DOCX 页数:15 大小:220.80KB
下载 相关 举报
计算机操作系统实验报告Word文档格式.docx_第1页
第1页 / 共15页
计算机操作系统实验报告Word文档格式.docx_第2页
第2页 / 共15页
计算机操作系统实验报告Word文档格式.docx_第3页
第3页 / 共15页
计算机操作系统实验报告Word文档格式.docx_第4页
第4页 / 共15页
计算机操作系统实验报告Word文档格式.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

计算机操作系统实验报告Word文档格式.docx

《计算机操作系统实验报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《计算机操作系统实验报告Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。

计算机操作系统实验报告Word文档格式.docx

voidrelease(intfree)

{

p(s);

top++;

cout<

<

"

top="

top<

endl;

stack[top]=free;

v(s);

}

main()

inti;

for(i=0;

i<

10;

i++)stack[i]=-1;

stack[0]=0;

stack[1]=156;

stack[2]=254;

stack[3]=129;

stack[4]=23;

cobegin{getspace();

release(100);

}

for(;

top>

=0;

top--)

stack["

]="

stack[top]<

实验2、同步关系_奇数偶数

假定有三个进程R、W1、W2共享一个缓冲区B,而B每次只能存放一个整数。

当缓冲区中无数时,进程R可以从输入设备上读入一个整数并存入B中;

若存到B中的数是奇数,则允许进程W1将其取出打印;

若是偶数,则允许进程W2将其取出打印。

另外规定:

进程R必须等B中的数被取出打印后才能再存放下一个数,进程W1或W2对每次存入的数只能打印一次并且都不能从空的缓冲区中取数。

请用PV操作实现R、W1和W2三个进程的并发执行。

代码:

Intbuf;

semaphores1=1;

s2=0;

s3=0;

voidr()

{p(s1);

cout<

input"

cin>

>

buf;

if(buf%2)v(s2);

elsev(s3);

voidw1()

{p(s2);

w1'

buf="

buf<

v(s1);

voidw2()

{p(s3);

w2'

v(s1);

main(){

cobegin{

r();

w1();

w2();

实验二

一、实验目的

1.目的

1、进程通信是多任务协作的基础,具有广泛的应用。

2、熟悉Linux的基于消息队列的进程通信的系统调用,并实现一个简单的C/S结构的实例。

二、Linux环境下常见shell命令

cd改变当前的工作目录cd/usr/src

Ls列出当前目录的文件名及子目录名ls–l*.c

cp文件拷贝cp*.c/mnt/usb

rm删除文件rma.out

mkdir创建一个子目录mkdir/usr/myData

rmdir删除一个子目录rmdir/usr/myData

chmod设置文件的存取权限chmod777myCC.sh

fdisk查看文件系统fdisk–l

mount装载文件系统mount/dev/sda0/mnt/usb

umount卸载文件系统umount/mnt/usb

pwd显示当前工作目录pwd

ps显示当前运行的进程ps–a

kill删除运行中的进程kill3685

cc基本使用实例

用法结果说明

ccex2.c编译后生成可执行目标文件a.out

cc–oex2ex2.c编译后生成可执行目标文件ex2

cc–I/mnt/usb/includeex2.c编译器编译过程除了在默认路径、还可以在指定的路径/mnt/usb/include下查找源文件包含的头文件

cc–L/mnt/usb/libex2.c编译器在自动连接时,除了在默认路径、还可以在指定的路径/mnt/usb/lib下查找源文件用到的库文件.

另外在命令状态下:

DD:

剪切一行NDD:

剪切N行DW:

剪切一个单词NDW:

剪切N个单词P:

粘贴YY:

复制一行NYY:

复制N行YW:

复制一个单词NYW:

复制N个单词

虚拟机里linux对u盘的操作

首先在终端输入:

fdisk–l

然后会看到下面的信息:

红线所画的就是我们的优盘

接下来,创建一个文件夹用于映射u盘,具体命令如下:

mkdirdinglin

mount/dev/sdb1dinglin

(dev表示device,sdb1就是优盘的编号,这句话表示吧优盘映射到dinglin文件夹)

现在,已经成功把优盘映射到dinglin文件夹

然后输入以下命令,进入优盘并查看文件

Cddinglin

Ls

(从图片中可以看到我们需要的两个文件:

cnt.c,svr.c)

接下来要做的便是把文件备份一下,具体操作如下:

输入以下代码:

Cdroot

Mkdirdisk

Cp/root/dinglin/cnt.c/root/disk

Cp/root/dinglin/svr.c/root/disk

Cddisk

第一句,因为刚刚我们通过cddinglin进入了U盘,所以现在要返回root文件夹下面,不然文件夹就建到了U盘里面

第2句:

因为新终端默认打开的是root文件夹,这句话表示在root文件夹下面新建了disk文件夹

第3、4句:

虽然我们已经新建了disk,但是我们还在root文件夹下面,所以要输入完整的路径才能把文件复制到指定文件夹,/root/dinglin/svr.c表示源文件位置,/root/disk表示目标路径

在复制文件的时候还有其他种方法,这里就不贴图了

Cd/root

Mkdirdisk

Cpcnt.c/root/disk

Cd/root/disk

这种方法是进入U盘把文加复制过去,因为进入了dinglin文件夹,所以不需要输入完整的文件源地址

现在,可以开始编译和运行了,操作如下

Cc–ocntcnt.c

./cnt

第一句表示把cnt.c编译问指定文件名的程序,第一个cnt就是编译后的文件的名称,后面的cnt.c是我们的源文件

通过ls命令。

我们看到文件夹里面多出一个cnt的文件,现在,直接输入./cnt运行就可以了

运行完毕之后就是卸载U盘了,操作如下

Umountdinglin

因为我们在root下面建的dinglin,所以必须返回root才能umount,如果显示deviceisbusy,说明你可能有其他终端打开了U盘而没有退出去,直接把其他终端关闭,在执行一次就ok了

 

三、消息队列通信

消息机制提供四个系统调用,分别是:

intmsgget(key_tkey,intmsgflg);

intmsgsnd(intmsgqid,structmsgbuf*msgp,size_tmsgsz,intmsgflg)

intmsgrcv(intmsgqid,structmsgbuf*msgp,size_tmsgsz,longmsgtyp,intmsgflg)

intmsgctl(intmsgqid,intcmd,structmsgqid_ds*buf)

注意:

在使用各种通信机制的系统调用前,必须include三个头文件:

sys/types.h>

sys/ipc.h>

sys/msg.h>

1)intmsgget(key_tkey,intmsgflg);

参数KEY是一个键值,由FTOK获得;

MSGFLG参数是一些标志位。

该调用返回与健值KEY相对应的消息队列描述字。

在以下两种情况下,该调用将创建一个新的消息队列:

•如果没有消息队列与健值KEY相对应,并且MSGFLG中包含了IPC_CREAT标志位;

•KEY参数为IPC_PRIVATE;

参数MSGFLG可以为以下:

IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或结果。

调用返回:

成功返回消息队列描述字,否则返回-1。

注:

参数KEY设置成常数IPC_PRIVATE并不意味着其他进程不能访问该消息队列,只意味着即将创建新的消息队列。

2)intmsgrcv(intmsgqid,structmsgbuf*msgp,size_tmsgsz,longmsgtyp,intmsgflg)

该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。

msqid为消息队列描述字;

消息返回后存储在msgp指向的地址,msgsz指定msgbuf的mtext成员的长度(即消息内容的长度),msgtyp为请求读取的消息类型;

读消息标志msgflg可以为以下几个常值的或:

•IPC_NOWAIT如果没有满足条件的消息,调用立即返回,此时,errno=ENOMSG

•IPC_EXCEPT与msgtyp>

0配合使用,返回队列中第一个类型不为msgtyp的消息

•IPC_NOERROR如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将丢失。

msgrcv手册中详细给出了消息类型取不同值时(>

0;

<

=0),调用将返回消息队列中的哪个消息。

msgrcv()解除阻塞的条件有三个:

1.消息队列中有了满足条件的消息;

2.msqid代表的消息队列被删除;

3.调用msgrcv()的进程被信号中断;

成功返回读出消息的实际字节数,否则返回-1。

3)intmsgsnd(intmsgqid,structmsgbuf*msgp,size_tmsgsz,intmsgflg)

向msgid代表的消息队列发送一个消息,即将发送的消息存储在msgp指向的msgbuf结构中,消息的大小由msgze指定。

对发送消息来说,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待。

造成msgsnd()等待的条件有两种:

•当前消息的大小与当前消息队列中的字节数之和超过了消息队列的总容量;

•当前消息队列的消息数(单位"

个"

)不小于消息队列的总容量(单位"

字节数"

),此时,虽然消息队列中的消息数目很多,但基本上都只有一个字节。

成功返回0,否则返回-1。

4)intmsgctl(intmsgqid,intcmd,structmsgqid_ds*buf)

该系统调用对由msqid标识的消息队列执行cmd操作,共有三种cmd操作:

IPC_STAT、IPC_SET、IPC_RMID。

1.IPC_STAT:

该命令用来获取消息队列信息,返回的信息存贮在buf指向的msqid结构中;

2.IPC_SET:

该命令用来设置消息队列的属性,要设置的属性存储在buf指向的msqid结构中;

可设置属性包括:

msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes,同时,也影响msg_ctime成员。

3.IPC_RMID:

删除msqid标识的消息队列;

四、消息队列应用实例

(1)题目:

基于通信的字符串传递,实现在客户端输入一个字符串,服务器端进行倒序,再到客户端输出。

client.c

#include<

#defineMSGKEY75

structmsgform

longmtype;

charsour[256];

chardest[256];

intsour_pid;

charmtext[256];

};

intlength=sizeof(structmsgform)-sizeof(long);

structmsgformmsg;

intmsgqid,pid;

msgqid=msgget(MSGKEY,0777);

printf("

msgqid=%d\n"

msgqid);

pid=getpid();

inputstring:

);

scanf("

%s"

&

msg.sour);

msg.sour_pid=pid;

msg.mtype=1;

msgsnd(msgqid,&

msg,length,0);

msgrcv(msgqid,&

msg,length,msg.sour_pid,0);

client:

msgqid=%d\n"

receivefrompid=%d\n"

msg.sour_pid);

receivestringis%s\n"

msg.dest);

server.c

}msg;

intmsgqid;

inti,pid;

externcleanup();

20;

i++)

signal(i,cleanup);

msgqid=msgget(MSGKEY,0777|IPC_CREAT);

serverisready...\npid=%d\n"

getpid());

;

{

msgrcv(msgqid,&

msg,length,1,0);

printf("

server:

receivefrompid=%d\n"

clientstringis%s\n"

msg.sour);

msg.mtype=msg.sour_pid;

msg.sour_pid=getpid();

intj=0;

intlen=strlen(msg.sour);

for(i=len-1;

i>

i--)

msg.dest[j++]=msg.sour[i];

stringis%s\n"

msgsnd(msgqid,&

cleanup(){

msgctl(msgqid,IPC_RMID,0);

exit(0);

}

(2)两个进程利用通信进行协作,实现简单的四则运算。

一个进程称为客户进程(Client),其任务是从键盘上接收3个参数:

两个操作数和一个运算操作符,然后把这3个参数发送给另一个进程,即服务器进程(Server);

服务器进程接收客户进程的请求,并根据提供的运算操作符,对两个操作数进行运算,服务器把运算的结果返回给客户。

client:

floata,b,result;

charf[3];

inputa="

%f"

msg.a);

inputb="

msg.b);

inputoperator="

msg.f);

if(msg.f[0]=='

/'

&

&

msg.b==0){

Error\n"

return0;

result=%f\n"

msg.result);

structmsgform{

serveriswaiting...\n"

a=%f\n"

msg.a);

b=%f\n"

msg.b);

f=%s\n"

msg.f);

if(msg.f[0]=='

+'

msg.result=msg.a+msg.b;

elseif(msg.f[0]=='

-'

msg.result=msg.a-msg.b;

*'

msg.result=msg.a*msg.b;

msg.result=msg.a/msg.b;

%f%s%f=%f\n"

msg.a,msg.f,msg.b,msg.result);

}}

实验心得:

每一次课程设计度让我学到了在平时课堂不可能学到的东西。

所以我对每一次课程设计的机会都非常珍惜。

不一定我的课程设计能够完成得有多么完美,但是我总是很投入的去研究去学习。

总结一下有以下体会。

1、同学间的讨论,这是很重要的。

老师毕竟比较忙。

对于课程设计最大的讨论伴侣应该是同学了。

能和学长学姐讨论当然再好不过了,没有这个机会的话,和自己班上同学讨论也是能够受益匪浅的。

大家都在研究同样的问题,讨论起来,更能够把思路理清楚,相互帮助,可以大大提高效率。

2、敢于攻坚,越是难的问题,越是要有挑战的心理。

这样就能够达到废寝忘食的境界。

当然这也是不提倡熬夜的,毕竟有了精力才能够打持久战。

但是做课设一定要有状态,能够在吃饭,睡觉,上厕所都想着要解决的问题,这样你不成功都难。

3、最好在做课设的过程中能够有记录的习惯,这样在写实验报告时能够比较完整的回忆起中间遇到的各种问题。

比如当时我遇到我以前从未遇到的段错误的问题,让我都不知道从何下手。

在经过大量的资料查阅之后,我对段错误有了一定的了解,并且能够用相应的办法来解决。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1