操作系统报告Word下载.docx
《操作系统报告Word下载.docx》由会员分享,可在线阅读,更多相关《操作系统报告Word下载.docx(11页珍藏版)》请在冰豆网上搜索。
Wait()和signal()函数在同一个线程中成对,中间为临界区。
同步时,semaphore一般等于资源数量。
Wait()和signal()分别在不同的线程里面。
6.消息队列:
发送消息时:
先准备好消息buffer,然后通过找到tcb的id,互斥访问接收线程的消息队列,把消息挂到消息队列上去,最后,同步,通知接收线程来取。
接收消息是:
互斥访问自己的消息队列,把消息放到自己的消息buffer里面,最后通知发送者,消息取走了。
下面是写的一点代码
共享变量:
intcount=36;
semaphoresem={1,NULL};
voidp_set(void){
inti,j,k;
for(i=0;
i<
15;
i++){
p(&
sem);
count--;
printf("
p_set--,count=%d\n"
count);
v(&
for(j=0;
j<
10000;
j++)
for(k=0;
k<
2000;
k++);
}
}
voidp_test(void){
count++;
p_test++,count=%d\n"
for(j=0;
3000;
吃苹果问题,5个buffer我没有区别对待所以,没用in和out等。
structsemaphore
{
intvalue;
structTCB*wq;
}plate_sm,apple_sm,orange_sm;
voidinit(){
plate_sm.value=6;
plate_sm.wq=NULL;
apple_sm.wq=NULL;
apple_sm.value=0;
orange_sm.value=0;
orange_sm.wq=NULL;
voidsignal(semaphore*sem){
structTCB**qp;
disable();
qp=&
(sem->
wq);
sem->
value=sem->
value+1;
if(sem->
value<
=0)/*判断信号量中value值,是否应该唤醒因这个信号量互斥操作,而阻塞的线程*/
wakeup(qp);
enable();
voidwait(semaphore*sem){
disable();
value-1;
0){
block((unsigned*)sem,qp);
inttemp;
voidfather(){
\nfatherrunning\n"
);
temp=rand();
if(temp%2==0){
wait(&
plate_sm);
fathreputanapple\n"
signal(&
apple_sm);
}
else{
wait(&
fatherputanorange\n"
orange_sm);
voidson(){
\nsonrunning\n"
printf("
soneatapple\n"
if(orange_sm.value>
onlyorangeNOEAT\n"
voiddaughter(){
\ndaughterrunning\n"
daughtereatorange\n"
if(apple_sm.value>
onlyappleNOEAT\n"
最后有一个优先权的时间片调度没有写好,我现在大概知道为什么没有实现。
可能是没用interrupt关键字。
文件系统的实现
已实现的功能:
创建文件,创建目录,cd,读写文件,还有就是可以存到文件中去,读出来还有可以看到原先创建的文件以及写入的东西。
没实现的主要是,当多于一个盘块时,找fat表时有点不太正确。
参考了Linux中的VFS层的实现,目录项的组织我用的是数组的下标没用原先的盘块号以及盘块的第几个目录项。
Linux中用的双向循环队列,目录项指向inode,我的实现中用的内存fcb表和目录项一起的,也就是没有分开。
Cd函数,我用“/”来分割目录,通过目录项中的father下标来确定父子目录关系。
假如一个文件已经调用了open,则不需要读写盘块,可以直接通过father下标来确定父子关系,不需要的再读盘块了,这是一个比较大的改进。
下面是关键代码:
打开文件:
voidadd_openfile(fcbf,intfather_fd){
//intblock以及off偏移量没有实现
openfilelist[open_count].open_fcb=f;
openfilelist[open_count].father=father_fd;
openfilelist[open_count].file_p=0;
//openfilelist->
count=1;
strcpy(currentdir,f.filename);
//currentdir[6]='
\0'
;
//strcpy(openfilelist[open_count].dir,currentdir);
current_dir=open_count;
open_count++;
创建文件以及目录
intmy_mkdir(char*dirname,intattr){
father=openfilelist[current_dir].open_fcb.first;
gran_father=openfilelist[current_dir].father;
time_t*now;
now=(time_t*)malloc(sizeof(time_t));
structtm*nowtime;
father_fd=current_dir;
fcb*base;
%s\n"
currentdir);
current=(fcb*)(myvhard+openfilelist[current_dir].open_fcb.first*BLOCKSIZE);
base=current;
intcount=openfilelist[current_dir].open_fcb.length/sizeof(fcb);
for(inti=0;
count;
i++,current++){
if(strcmp(file,current->
filename)==0)
{
printf("
文件重名\n"
return-1;
//这个是需要修改父目录文件的,假如文件超过一块的大小,需要再分配一块,
//用显示连接,再fat表中那一个指出下一块的位置
fat*fat1,*fat2;
fcb*new_fcb;
fat1=(fat*)myvhard+BLOCKSIZE;
fat2=(fat*)myvhard+3*BLOCKSIZE;
//这里开始写错了
fat*cru;
inti;
for(i=7,cru=fat1;
1000;
i++,cru++){
if(cru->
id==FREE)
break;
if(i==1000)
//每次==总是只写一半尼玛
没有空闲块\n"
return0;
//没有找到空闲盘块
cru->
id=END;
fat2+=i;
fat2->
//修改fat表
time(now);
nowtime=localtime(now);
unsignedchar*p=myvhard+i*BLOCKSIZE;
//这个新建目录文件起始盘块地址
//目录文件的初始化
if(attr){
init_dentry(p,i,father);
//只有目录才需要初始化
intnum=openfilelist[gran_father].open_fcb.length/sizeof(fcb);
unsignedchar*gran_fa=(unsignedchar*)myvhard+BLOCKSIZE*openfilelist[gran_father].open_fcb.first;
fcb*temp=(fcb*)gran_fa;
num;
i++,temp++){
if(!
strcmp(temp->
filename,openfilelist[father_fd].open_fcb.filename))
//printf("
father****%s\n"
temp->
filename);
/*if(!
strcmp("
/"
openfilelist[gran_father].open_fcb.filename))
((fcb*)(myvhard+5*BLOCKSIZE))->
length+=sizeof(fcb);
//*******这个要注意
*/
openfilelist[current_dir].open_fcb.filename))
temp->
//printf("
father%d\n"
length/sizeof(fcb));
//修改父目录文件的大小,需要到父目录的父目录找到它,修改大小
//修改父目录文件的大小,以及加入一个新的fcb;
//父目录中加入mkdir的fcb控制块
//
base+=count;
base->
time=nowtime->
tm_hour*2048+nowtime->
tm_min*32+nowtime->
tm_sec/2;
data=(nowtime->
tm_year-80)*512+(nowtime->
tm_mon+1)*32+nowtime->
tm_mday;
if(attr)
length=2*sizeof(fcb);
else
length=0;
if(attr==1)
attribute=1;
attribute=0;
//创建文件
first=i;
//起始块
//base->
length+=2*sizeof(fcb);
尼玛多写了一句,找了好久
strcpy(base->
filename,file);
exname,"
\0"
exname,extend);
openfilelist[current_dir].dirty=1;
//脏位
openfilelist[current_dir].open_fcb.length+=sizeof(fcb);
//修改父目录文件长度
//openfilelist[current_dir].open_fcb.length=base->
length;
//openfilelist[current]
add_openfile(*base,father_fd);
创建成功\n"
return1;
//表示成功
intmy_cd(char*dirname){
fcb*current;
intfather;
intgran_father=openfilelist[current_dir].father;
intflag=0;
strcmp(dirname,"
.."
)){
current_dir=gran_father;
return1;
if(*dirname=='
/'
){
father=0;
//根目录下
father=current_dir;
//father指向当前打开目录
intcount=spilit(dirname);
//在打开文件表中找,当一个目录分量找不到时,跳出来,去文件中找
//假如文件中没有的话,显示错误。
intj;
for(i=0;
flag=0;
for(j=0;
open_count;
j++){
if(openfilelist[j].father==father&
&
openfilelist[j].open_fcb.attribute==1&
!
strcmp(openfilelist[j].open_fcb.filename,inode[i]))
{
father=j;
flag=1;
//表示在打开文件表中找到了
break;
//跳出本次循环
}
if(flag==0)
//在打开文件表中没有找到,接下来到目录块中去找
break;
//跳出查找
if(flag==1){
//把当前目录替换掉
current_dir=j;
在打开文件中找到\n"
intsave_dir=current_dir;
//保存当前目录,下面应该可以用到的
if(dentry_find(i,count,father))
在目录文件中打开\n"
//没有找到这个
current_dir=save_dir;
//
没有找到这个目录\n"
strcpy(currentdir,openfilelist[current_dir].open_fcb.filename);
return0;
下面是实验图