资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,1,2.6,设备管理,打开一个设备文件即相当于申请对应的设备,如该设备已处于打开状态则等待,关闭一个设备文件即相当于释放对应的设备,如有等待者则唤醒一个,读写一个设备文件就相当于对所对应的设备执行,I/O,操作,缓冲与缓存,块型设备缓冲,用于磁盘、磁带等设备的,I/O,传输,每个缓冲区的长度与块型物理设备中一个块的长度相同,即为512字节,缓冲区为所有块型设备公用,其总数为15个,块型设备缓冲,struct buf,int b_flags;/*see definition below*/,struct buf*b_forw;/*headed by devtab of b_dev*/,struct buf*b_back;/*,设备,b,链向后指针*/,struct buf*av_forw;/*av,链向前指针*/,struct buf*av_back;/*av,链向后指针*/,int b_dev;/*,设备名*/,int b_wcount;/*,传送字数*/,char*b_addr;/*,内存地址(低位)*/,char*b_xmem;/*,内存地址(高位)*/,char*b_blkno;/*,设备物理块号*/,char b_error;/*,返回出错信息*/,char*b_resid;/*,传送剩余字节*/,bufNBUF;,块型设备控制结构,struct devtab,char d_active;/*busy flag*/,char d_erncnt;/*error count*/,struct buf*b_forw;/*first buffer for this dev*/,struct buf*b_back;/*last buffer for this dev*/,struct buf*d_actf;/*head of IO queue*/,struct buf*d_actl;/*tail of IO queue*/,块缓冲数据读写,内存区,缓冲区,磁盘块,iomove,bread,breada,bwrite,bawrite,bdwrite,字符型设备缓冲,缓冲池,struct cblock,struct cblock*c_next;/*pointer*/,char info6;/*info container*/,读操作,写操作,预先读与延迟写,预先读,(,read ahead),将以后即将使用的块读入缓冲区中,以后进程需要该块时便可在缓冲区中直接得到,不必等待设备,I/O,传输,基于文件顺序访问的假设,预先读函数,breada(dev,blkno,rablkno),rablkno,链入,d,链,IO,完成放入,b,链和,av,链,预先读与延迟写,延迟写,(,delayed write),当一个缓冲块尚未写满时,暂不将其写到外存,以后继续写时,不必将该块由外存读入内存,延迟写,函数,bdwrite(bp),将,bp,对应的缓冲区链入,b,链和,av,链,若以后还需要读写,可在缓冲区中得到,.,缓冲区在,av,链上取到用作其它用途前,由,b,链换到,d,链,写回外存,.,12.7 系统调用,地位,操作系统,API,One of Programmer Interface,The other being,System,Libs,主要包括,Process manipulation,File manipulation,Communication,Others,12.7.1,有关进程的系统调用命令,相关系统调用,创建子进程,Pid,=,fork(),子进程是父进程的复制品,返回值:父进程为子进程编号,子进程为,0,加载并执行新程序,execl(prog,arg0,argn-1,0),以,arg0,argn-1,为参数执行,prog,覆盖原来程序,从第一条指令开始执行,12.7.1,有关进程的系统调用命令,进程自我结束,exit(status),Status,为终止状态,唤醒父进程,等待子进程终止,pid=wait(&status),返回终止子进程编号,参数为子进程的终止状态,proc,结构,p_pid=9,p_ppid=5,user,结构,pid=fork();,if(pid=0)/*,成立*/,/*子进程代码*/,else,/*,父进程代码*/,proc,结构,p_pid=12,p_ppid=9,user,结构,复制,父进程,子进程,fork(),创建子进程,联系,子进程号,(,0整数,),pid=fork();,if(pid=0)/*,不成立*/,/*子进程代码*/,else,/*,父进程代码*/,恒为0,pid=fork();,if(pid=0)/*,不成立*/,execl(“P”,0);,else,/*,父进程代码*/,proc,结构,p_pid=9,p_ppid=5,user,结构,pid=fork();,if(pid=0)/*,成立*/,execl(“P”,0);,else,/*,父进程代码*/,proc,结构,p_pid=12,p_ppid=9,user,结构,父进程,子进程,execl(),加载并执行新程序,pid=fork();,if(pid=0)/*,不成立*/,execl(“P”,0);,else,/*,父进程代码*/,proc,结构,p_pid=9,p_ppid=5,user,结构,程序,P,(,覆盖原来程序),proc,结构,p_pid=12,p_ppid=9,user,结构,父进程,子进程,execl(),加载并执行新程序,pid=fork();,if(pid=0)/*,不成立*/,execl(“P”,0);,else,/*,父进程代码*/,id=wait(&s),proc,结构,p_pid=9,p_ppid=5,user,结构,程序,P(,覆盖原来程序),exit(2),proc,结构,p_pid=12,p_ppid=9,user,结构,父进程,子进程,exit(),进程自我终止,P1,P2 P3 P4,P5 P6,P7,P8,例子:,设有8个程序,执行次序如下图所示,试用,fork,execl,wait,exit,系统调用描述之,main(),int pid1,pid2,pid3,pid4,pid5,pid6,pid7,pid8;,int end_p1=end_p2=end_p3=end_p4=end_p5=end_p8=0;,int pid,status;,if(pid1=fork()=0)execl(P1,0);,wait(,if(pid2=fork()=0)execl(P2,0);,if(pid3=fork()=0)execl(P3,0);,if(pid4=fork()=0)execl(P4,0);,do /,等待,P2,结束,pid=wait(,if(pid=pid2)end_p2=1;,if(pid=pid3)end_p3=1;,if(pid=pid4)end_p4=1;,while(end_p2=0);,if(pid5=fork()=0)execl(P5,0);,if(pid6=fork()=0)execl(P6,0);,do /,等待,P3,和,P6,结束,pid=wait(,if(pid=pid3)end_p3=1;,if(pid=pid4)end_p4=1;,if(pid=pid5)end_p5=1;,if(pid=pid6)end_p6=1;,while(end_p3=0|end_p6=0);,if(pid7=fork()=0)execl(P7,0);,do /,等待,P4,P5,P7,结束,pid=wait(,if(pid=pid4)end_p4=1;,if(pid=pid5)end_p5=1;,if(pid=pid7)end_p7=1;,while(end_p4=0|end_p5=0|end_p7=0);,if(pid8=fork()=0)execl(P8,0);,wait(,exit(0);,vfork,与,fork,fork,功能,复制地址空间(,code+data+stack),复制控制结构(,proc,user),特点,父子进程之间有两个各自独立的数据拷贝,问题,不加载新程序,不能实现数据共享,不能描述诸如“有界缓冲区”问题,若加载新程序,复制没有意义,浪费时间和空间,vfork,与,fork,vfork,只复制控制结构(,proc+user);,不复制地址空间(,code+data),父子进程共享地址空间,使用,父进程使用,vfork,创建子进程;,子进程与父进程共享地址空间;,子进程使用,execve,改变其虚拟地址空间.,12.7.2,有关文件的系统调用命令,创建文件,fd=creat(path_name,mode),分配一个,inode,填写目录项,以写方式打开该文件,返回文件描述符,打开文件,fd=open(path_name,mode),查目录找到,inode,权限检查,(mode,i_mode,i_uid,i_gid,u_uid,u_gid),在,file,表中分配一个表项,指向该内存,inode,在,u_ofile,中取一表目,指向,file,表中对应表目,返回文件描述符,fd,有关文件的系统调用命令,关闭文件,close(fd),由,fd,查,u_ofile,找到对应入口,由,u_ofilefd,找到,file,表对应入口,f_count-,若,f_count=0,i_count,若,i_count=0,且,i_node,修改过,i_node,写回外存,u_ofilefd=-1(,空闲标志),有关文件的系统调用命令,读命令,n_rd=read(fd,buf,bytes),由,u_ofilefd,,找到,file,表对应入口,检查访问权限(,f_flag,READ),由,f_inode,找到内存,inode,入口,由,f_offset,count,和,i_addr,计算磁盘块号(可能多个块)(,bmap,函数),启动,I/O,设备读取盘块到系统缓冲区中(如,buffer,无,切换进程),缓冲区信息复制到进程空间(,iomove),返回实际传输字节数,nrd,有关文件的系统调用命令,写文件,n_wt=write(fd,buf,bytes),由,u_ofilefd,,找到,file,表对应入口,检查访问权限(,f_flag,WRITE),由,f_inode,找到内存,inode,入口,由,f_offset,count,和,i_addr,计算磁盘地址块号(可能分配盘块),申请系统缓冲区,将,buf,起始,count,数据送到缓冲区中(可多次),缓冲区链到设备,I/O,链上,如设备空闲启动设备,修改,inode,中文件长度,i_size,返回实际传输字节数,nwt,有关文件的系统调用命令,文件指针定位,seek(fd,offset,origin),由,u_ofilefd,找到,file,表入口,由,f_inode,找到内存,inode,检查参数合法性(,i_size0,i_size1,f_offset,offset),按参数要求调整,f_offset,指针,有关文件的系统调用命令,建立文件链接,link(old_name,new_name),查目录找到,oldpathname(inode),查目录找到,newpathname,的末级目录,检查操作合法性,Inode,的,i_nlink+,(name,i_number),末级目录,断开文件链接,unlink(path_name),查目录找到,pathname(inode),i_nlink-;,如结果为0,释放所有磁盘块(删除文件),清除末级文件名在末级目录中的登记,有关文件的系统调用命令,建立管道,pipe(fd),分配一个,inode,(i_flag,标志为,PIPE,文件,,i_count=2),分配2个
展开阅读全文