操作系统课设报告Word文档格式.docx
《操作系统课设报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《操作系统课设报告Word文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
/bin:
存放常用命令
/boot:
引导核心的程序目录
/dev:
外部设备名
/etc:
(etcetera)系统管理所要的配置文件和子目录
/home:
存放用户主目录的地方,一般是/home/用户名。
其他目录有ftp、httpd、samba等
/lib:
(library)系统基本的动态链接库
/lost+found
/opt:
optional(可以选择的)
/proc:
:
虚拟系统,是由系统初起时在内存中产生的
/root:
超级用户默认的主目录;
/sbin:
系统管理员使用的系统管理程序
/tmp:
存放各程序执行时所产生的临时文件
/usr:
占空间最大的目录,用户的很多应用程序和文件几乎全在这个目录中 /var:
存放一些系统记录文件和配置文件
一、LUNIX的登录与退出
1、登录
在DOS环境下用MS提供的telnet程序(也可使用WINDOWS自带的telnet图形界面程序或多功能的S-Term终端程序),可使PC作为终端(terminal)登录(login)UNIX服务器(UNIXServer)。
(1)步骤
login:
(输入username)
password:
(输入密码)
2、退出
在LUNIX系统提示符$下,输入logout、exit或shutdown。
例:
$logout
二、LUNIX命令格式
命令[选项][处理对象]
ls-lamydir
注意:
(1)命令一般是小写字串。
注意大小写有别
(2)选项通常以减号(-)再加上一个或数个字符表示,用来选择一个命令的不同操作
(3)同一行可有数个命令,命令间应以分号隔开
(4)命令后加上&
可使该命令后台(background)执行
二.本次实验所用到的指令
1.安装U盘:
ldisk-l
cd/mnt
mkdir"
文件名"
mount、dev/sdb1/mnt/"
cd/mnt/"
ls
2.编译执行程序:
gccf1.c-of1.out
./f1.out
4.设计过程
1.分析与设计思路
分析:
通过仔细分析可以知道这是一个进程同步问题的模拟,可以把生产产品或消费产品的每一个过程可以转为一个进程的操作,这些进程是互斥的,同时也存在一定的同步关系。
通过编程实践时,实际是随机的调用一个进程的操作,而这些进程的操作相当于程序中的函数调用。
而计算机在执行时每一个时刻只能执行一个操作,这就默认了互斥。
同步的模拟可以类似于函数调用时的前提关系即先决条件。
这样进程同步模拟就完全可以通过进程来实现。
具体的每一个操作的对应的进程的关系:
实现对缓冲区的初始化:
main,要最先执行,且只需要执行一次
生产者1生产产品:
producer1.c
生产者2生产产品:
producer2.c
消费者1消费产品:
consumer1.c
消费者2消费产品:
consumer2.c
在次程序中信号量、共享缓冲区都是系统资源,其总个数是有上限的。
每个资源的id在系统中唯一,并且系统不会主动释放它们,所以要小心使用,及时释放。
在本程序中:
main在执行一次后(成功执行),信号量、共享缓冲区就会分配。
如果再执行它,main会提示资源已经分配,则要释放它们。
设计思路:
设计了4个信号量:
semid_empty:
表示缓冲区中可以再进行产品添加的空间数
semid_full1:
表示生产者1所生产的产品数
semid_full2:
表示生产者2所生产的产品数
semid_mux:
表示其公共的信号量。
设置了4个进程来实现功能:
2.各模块流程图
P、V操作的流程图:
2.生产者与消费者流程图
Y
N
5.源代码与实验结果
数据结构
voidset_sembuf_struct(structsembuf*sem,intsemnum,intsemop,intsemflg)
{
/*设置信号量结构*/
sem->
sem_num=semnum;
sem_op=semop;
sem_flg=semflg;
}
/*
sem_num:
操作信号在信号集中的编号,第一个信号的编号是0。
sem_op:
如果其值为正数,该值会加到现有的信号内含值中。
通常用于释放所控资源的使用权;
如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。
通常用于获取资源的使用权;
如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。
sem_flg:
信号操作标志
*/
主程序:
main.c
#include<
sys/types.h>
sys/ipc.h>
sys/shm.h>
sys/sem.h>
errno.h>
string.h>
stdio.h>
#defineSHMKEY9075/*共享存储区的键*/
#defineSEMKEY_PRODUCER9085
#defineSEMKEY_CONSUMER9086
#defineSEMKEY_MUTEX9087/*信号量数组的键*//*注意:
上面的键在系统中必须唯一*/
#defineBUFF_LEN5/*缓冲区可以存放5个产品*/
#definePRODUCER_LEN32/*每个产品是一个字符串:
<
=32字符*/
intmain()
{
char*addr,end;
intshmid;
/*共享存储区id*/
intsemid_producer,semid_consumer,semid_mutex;
/*信号量集合id*/
structsembufsem_tmp;
/*开辟共享存储区*/
if((shmid=shmget(SHMKEY,BUFF_LEN*PRODUCER_LEN+2,0777|IPC_CREAT|IPC_EXCL))==-1)
{
if(errno==EEXIST)
{
printf("
TheBufferHasExisted!
\n"
);
DoYouWantToDeleteTheBuffer(Y=yes)?
\n=:
"
scanf("
%c"
&
end);
if(end=='
y'
||end=='
Y'
)
{
/*释放缓冲区*/
shmid=shmget(SHMKEY,BUFF_LEN*PRODUCER_LEN+2,0777);
if(shmctl(shmid,IPC_RMID,0)<
0)
perror("
shmctl:
/*同时释放信号量*/
semid_mutex=semget(SEMKEY_MUTEX,1,0777);
semid_producer=semget(SEMKEY_PRODUCER,1,0777);
semid_consumer=semget(SEMKEY_CONSUMER,1,0777);
semctl(semid_mutex,0,IPC_RMID);
semctl(semid_producer,0,IPC_RMID);
semctl(semid_consumer,0,IPC_RMID);
}
}
else
Failtocreatebuffer!
return-1;
}
addr=(char*)shmat(shmid,0,0);
/*连接缓冲区,将一个共享存储区附接到它的虚拟地址空间去*/
memset(addr,0,BUFF_LEN*PRODUCER_LEN+2);
/*将addr所指向的某一块内存中的每个字节的内容全部设置为0的ASCII值,块的大小由BUFF_LEN*PRODUCER_LEN+2指定,返回值为指向addr的指针*/
shmdt(addr);
/*离开缓冲区*/
/*创建信号量*/
if((semid_mutex=semget(SEMKEY_MUTEX,1,0777|IPC_CREAT|IPC_EXCL))==-1)
TheSEMKEY_MUTEXhasexisted!
FailtocreateSEMKEY_MUTEX!
if((semid_producer=semget(SEMKEY_PRODUCER,1,0777|IPC_CREAT|IPC_EXCL))==-1)
TheSEMKEY_PRODUCERhasexisted!
FailtocreateSEMKEY_PRODUCER!
if((semid_consumer=semget(SEMKEY_CONSUMER,1,0777|IPC_CREAT|IPC_EXCL))==-1)
TheSEMKEY_CONSUMERhasexisted!
FailtocreateSEMKEY_CONSUMER!
/*给信号量赋初值*/
set_sembuf_struct(&
sem_tmp,0,BUFF_LEN,0);
/*BUFF_LEN*/
semop(semid_producer,&
sem_tmp,1);
sem_tmp,0,1,0);
/*1*/
semop(semid_mutex,&
sem_tmp,0,0,0);
/*0*/
semop(semid_consumer,&
return0;
}
/*生产者:
producer.c*/
#definePRODUCT_LEN32/*每个产品是一个字符串:
/*下面的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)/*返回在该组操作中最后被操作的信号量在操作完成前的值*/
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"
}
main()
char*p_buffer;
/*共享存储区地址*/
unsignedcharin;
/*生产者存放产品的指针:
它的值存放在全局缓冲区第一个字节*/
charproduct[128];
/*事实只使用32B,128为了避免屏幕输入超过32*/
intsemid_producer,semid_consumer,semid_mutex;
shmid=shmget(SHMKEY,BUFF_LEN*PRODUCT_LEN+2,0777);
/*连接共享存储区:
2存放in,out的值*/
/*shmget是建立新的共享区或返回一个已存在的共享描述字*/
p_buffer=(char*)shmat(shmid,0,0);
/*取共享存储区地址*/
/*获取全局信号量id*/
/*从屏幕接收产品*/
printf("
PleaseProduct(astring,length<
=32B):
\n====:
gets(product);
/*128的意义在此,此函数不检查字符串长度*/
/*进入临界区*/
P(semid_producer);
/*对私有信号量作P操作*/
P(semid_mutex);
/*对公有信号量作P操作*//*二者顺序不能换*/
in=(unsignedchar)(*p_buffer);
strncpy(p_buffer+2+in*PRODUCT_LEN,product,PRODUCT_LEN);
in=(in+1)%BUFF_LEN;
*p_buffer=(char)in;
shmdt(p_buffer);
/*离开缓冲区*/
/*离开临界区*/
V(semid_consumer);
V(semid_mutex);
/*获取生产者信号量id*/
/*获取消费者信号量id*/
#defineCONSUMER_LEN32/*每个产品是一个字符串:
p(s