操作系统课程设计报告PV操作Word格式文档下载.docx
- 文档编号:17909968
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:18
- 大小:87.08KB
操作系统课程设计报告PV操作Word格式文档下载.docx
《操作系统课程设计报告PV操作Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告PV操作Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
(一)实验原理
1.原理:
parents(包括father和mother)-->
|+++|(缓冲区:
存放3个水果)-->
daughter和son。
Parents和daughter、son通过共享缓冲区进行通信,信号量用于对缓冲区互斥访问、对parents和daughter、son进行同步。
2.共有五个程序:
control,father,mother,son,daughter.其中control是主控程序.
control:
实现对缓冲区的初始化,要最先执行,且只需要执行一次。
father:
把一个苹果放入缓冲区:
从屏幕输入一个字符串(32字节以内)。
Mother:
把一个橘子放入缓冲区:
Son:
从缓冲区取出一个橘子:
从屏幕上输出一个字符串。
Daughter:
从缓冲区取出一个苹果:
3.注意:
信号量、共享缓冲区都是系统资源,其总个数是有上限的。
每个资源的id在系统中唯一,并且系统不会主动释放它们,所以要小心使用,及时释放。
本程序中:
control在执行一次后(成功执行),信号量、共享缓冲区就会分配。
如果再执行它,control会提示资源已经分配,是否要释放它们?
如果键入y(Y),则资源释放,此后执行father,mother,son,daughter都会报错。
当然也可以使用ipcsipcrm命令来查看或释放资源。
4.为了结构清晰,程序没有多余的输入或输出。
在father,mother,son,daughter程序中适当的位置增加输出语句,和输入字符语句将程序暂停在某个位置,以观察运行的详细进程。
(二)虚拟机下linux挂载U盘
需要让你的虚拟机GuestOS(Linux)能自动识别U盘。
方法如下:
保持焦点在Linux上,插入U盘,这时宿主操作系统Windows会弹出“找到新设备的提示”,然后一步一步的点下一步,结束以后,就可以在linux使用fdisk-l/dev/sdb命令查看到/dev/sdb1。
在虚拟机识别出USB之后,用fdisk-l/dev/sdb或fdisk-l/dev/hdb查看,会看到U盘被识别为sdb1,使用mount命令挂载即可。
先在/mnt建一个新的文件夹,例如usb。
则可通过:
mount-tvfat/dev/sdb1/mnt/usb挂载上U盘
卸载使用:
umount/dev/sdb1
四、源程序
1.主控程序control.c
#include<
sys/types.h>
sys/ipc.h>
sys/shm.h>
sys/sem.h>
errno.h>
string.h>
#defineSHMKEY9075/*共享存储区的键*/
#defineSEMKEY_son9084
#defineSEMKEY_parents9085
#defineSEMKEY_daughter9086
#defineSEMKEY_MUTEX9087/*信号量数组的键*//*注意:
上面的键在系统中必须唯一*/
#defineBUFF_LEN3/*缓冲区可以存放3个产品*/
#definePRODUCT_LEN10/*每个产品是一个字符串:
<
=32字符*/
voidset_sembuf_struct(structsembuf*sem,intsemnum,intsemop,intsemflg)
{
/*设置信号量结构*/
sem->
sem_num=semnum;
sem_op=semop;
sem_flg=semflg;
}
main()
{
char*addr,end;
intshmid;
intsemid_parents,semid_daughter,semid_son,semid_mutex;
/*信号量id*/
structsembufsem_tmp;
/*开辟共享存储区*/
if((shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+4,0777|IPC_CREAT|IPC_EXCL))==-1)
{
if(errno==EEXIST)
printf("
TheBufferHasExisted!
\n"
);
DoYouWantToDeleteTheBuffer(Y=yes)?
\n====:
"
scanf("
%c"
&
end);
if(end=='
y'
||end=='
Y'
)
/*共享存储区、信号量并不随程序的结束而被删除,如果我们没删除的话,
可以用ipcs命令查看,用ipcrm删除
*/
/*释放缓冲区*/
shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+4,0777);
if(shmctl(shmid,IPC_RMID,0)<
0)
perror("
shmctl:
/*同时释放信号量*/
semid_mutex=semget(SEMKEY_MUTEX,1,0777);
semid_daughter=semget(SEMKEY_daughter,1,0777);
semid_parents=semget(SEMKEY_parents,1,0777);
semid_son=semget(SEMKEY_son,1,0777);
semctl(semid_mutex,0,IPC_RMID);
semctl(semid_daughter,0,IPC_RMID);
semctl(semid_parents,0,IPC_RMID);
semctl(semid_son,0,IPC_RMID);
}
else
FailToCreateBuffer!
return-1;
addr=(char*)shmat(shmid,0,0);
/*连接缓冲区*/
memset(addr,0,BUFF_LEN*PRODUCT_LEN+2);
shmdt(addr);
/*离开缓冲区*/
/*创建3个信号量:
1个用于对缓冲区互斥,2个用于生产者、消费者同步*/
if((semid_mutex=semget(SEMKEY_MUTEX,1,0777|IPC_CREAT|IPC_EXCL))==-1)
{
TheSEMKEY_MUTEXHasExisted!
FailToCreateSEMKEY_MUTEX!
}
if((semid_daughter=semget(SEMKEY_daughter,1,0777|IPC_CREAT|IPC_EXCL))==-1)
TheSEMKEY_daughterHasExisted!
FailToCreateSEMKEY_daughter!
if((semid_parents=semget(SEMKEY_parents,1,0777|IPC_CREAT|IPC_EXCL))==-1)
TheSEM_parentsHasExisted!
FailToCreateSEM_parents!
if((semid_son=semget(SEMKEY_son,1,0777|IPC_CREAT|IPC_EXCL))==-1)
TheSEMKEY_sonHasExisted!
FailToCreateSEMKEY_son!
/*给信号量赋初值*/
set_sembuf_struct(&
sem_tmp,0,3,0);
/*BUdaughterFF_LEN*/
semop(semid_parents,&
sem_tmp,1);
sem_tmp,0,0,0);
/*0*/
semop(semid_daughter,&
semop(semid_son,&
sem_tmp,0,1,0);
/*1*/
semop(semid_mutex,&
return0;
}
2.父亲:
father.c
#defineBUFF_LEN3/*缓冲区可以存放3个水果*/
#definePRODUCT_LEN6/*每个产品是一个字符串:
/*下面的P,V是对系统调用的简单封装*/
intP(intsemid)
structsembufp_buf;
p_buf.sem_num=0;
p_buf.sem_op=-1;
p_buf.sem_flg=0;
if(semop(semid,&
p_buf,1)==-1)/*semop参见课件ppt*/
perror("
p(semid)falsed"
exit
(1);
else
return(0);
intV(intsemid)
structsembufv_buf;
/*structsembuf参见课件ppt*/
v_buf.sem_num=0;
v_buf.sem_op=1;
v_buf.sem_flg=0;
v_buf,1)==-1)
v(semid)failed"
char*p_buffer;
/*共享存储区地址*/
unsignedcharin;
/*生产者存放产品的指针:
它的值存放在全局缓冲区第一个字节*/
charapple[6];
/*事实只使用32B,128为了避免屏幕输入超过32*/
/*共享存储区id*/
intsemid_parents,semid_daughter,semid_mutex;
/*信号量集合id*/
shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+4,0777);
/*连接共享存储区:
2存放in,out的值*/
p_buffer=(char*)shmat(shmid,0,0);
/*取共享存储区地址*/
/*获取全局信号量id*/
/*从屏幕接收产品*/
PleaseProduct(astring,length<
=32B):
gets(apple);
/*128的意义在此,此函数不检查字符串长度*/
/*进入临界区*/
P(semid_parents);
/*对私有信号量作P操作*/
P(semid_mutex);
/*对公有信号量作P操作*//*二者顺序不能换*/
in=(unsignedchar)(*p_buffer);
strncpy(p_buffer+4+in*PRODUCT_LEN,apple,PRODUCT_LEN);
in=(in+1);
*p_buffer=(char)in;
shmdt(p_buffer);
/*离开临界区*/
V(semid_daughter);
V(semid_mutex);
3.母亲:
mother.c
#defineSEMKEY_MUTEX9087/*信号量数组的键*//*注意:
charorange[6];
intsemid_parents,semid_son,semid_mutex;
gets(orange);
p_buffer=p_buffer+2;
in=(unsignedchar)(*p_buffer);
strncpy(p_buffer+2+(BUFF_LEN-1)*PRODUCT_LEN-in*PRODUCT_LEN,orange,PRODUCT_LEN);
in=(in+1);
p_buffer=p_buffer-2;
/*离开缓冲区*/
/*离开临界区*/
V(semid_son);
4.女儿:
daughter.c
#defineBUFF_LEN3/*缓冲区可以存放3个水果*/
unsignedcharout,in;
/*消费者取出产品的指针:
它的值存放在全局缓冲区第二个字节*/
charapple[33];
/*它的数据从缓冲区中取*/
P(semid_daughter);
p_buffer++;
out=(unsignedchar)(*p_buffer);
p_buffer=p_buffer-1;
in=(unsignedchar)(*p_buffer);
strcpy(apple,p_buffer+4+out*PRODUCT_LEN);
if(in==2)
strcpy(p_buffer+4+0*PRODUCT_LEN,p_buffer+4+1*PRODUCT_LEN);
if(in==3)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 报告 PV 操作