ImageVerifierCode 换一换
格式:DOC , 页数:14 ,大小:620.19KB ,
资源ID:4306997      下载积分:8 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/4306997.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(北京邮电大学操作系统实验-(2).doc)为本站上传会员【丰****】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

北京邮电大学操作系统实验-(2).doc

1、 操作系统 班级:2011211302 学号:2011211168 姓名:康雅微 目录 实验5.1 进程通信观察实验 实验6.3 I/O系统编程实验 实验7.1 文件管理系统管理实验代码分析 实验5.1 观察实验 1、实验目的与内容 在Linux下,用ipcs()命令观察进程通信情况,了解Linux基本通信机制。 2、实验原理 Linux IPC继承了Unix System V及DSD等,共有6种机制: 信号(signal)、管道(pipe和命名管道(named piped)、消息队列(message queues)、共享内存(sh

2、ared memory segments)、信号量(semaphore)、套接字(socket)。 本实验中用到的几种进程间通信方式: (1)共享内存段(shared memory segments)方式 – 将2个进程的虚拟地址映射到同一内存物理地址,实现内存共享 – 对共享内存的访问同步需由用户进程自身或其它IPC机制实现(如信号量) – 用户空间内实现,访问速度最快。 – Linux利用shmid_ds结构描述所有的共享内存对象。 (2)信号量(semaphore)方式 – 实现进程间的同步与互斥 – P/V操作, Signal/wait操作 – Linux利用se

3、mid_ds结构表示IPC信号量 (3)消息队列(message queues)方式 – 消息组成的链表,进程可从中读写消息。 – Linux维护消息队列向量表msgque,向量表中的每个元素都有一个指向msqid_ds结构的指针,每个msqid_ds结构完整描述一个消息队列 LINUX系统提供的IPC函数有: l msgget(关键字,方式):创建或打开一个消息队列 l msgsnd(消息队列标志符,消息体指针,消息体大小,消息类型): 向队列传递消息 l msgrcv(消息队列标志符,消息体指针,消息体大小,消息类型): 从队列中取消息 l msgctl(消息队列标志符,获

4、取/设置/删除,maqid_ds缓冲区指针): 获取或设置某个队列信息,或删除某消息队列 Linux系统中,内核,I/O任务,服务器进程和用户进程之间采用消息队列方式,许多微内核OS中,内核和各组件间的基本通信也采用消息队列方式. 3、实验结果 实验6.3 编程实验 1、实验目的 编写一个daemon进程,该进程定时执行 ps命令,然后将该命令的输出写至文件F1尾部。通过此实验,掌握Linux I/O系统相关内容。 2、实验原理 在这个程序中,首先fork一个子程序,然后,关闭父进程,这样,新生成的子进程被交给init进程接管,并在后台执行。 新生成的子进程

5、里,使用system系统调用,将ps的输出重定向,输入到f1.txt里面。 3、实验步骤 编写daemon.c 代码如下: #include #include int main(int argc,char* argv[]) { int i,p; p = fork(); if(p > 0){ exit(0); } else if(p == 0){ for(i = 0; i < 100; i++){ sleep(100); system("ps > f1.txt"); } } else{ perror("Create n

6、ew process!"); } return 1; } } 编译程序 # gcc -o daemon daemon.c 执行程序 # ./daemon 5、实验结果及分析 程序sleep(100)后会在当前目录生成一个文件f1.txt,内容如下: PID TTY TIME CMD 1258 pts/0 00:00:00 bash 2729 pts/0 00:00:00 daemon 2801 pts/0 00:00:00 sh 2802 pts/0 00:00:00 ps 再sleep(100),此文件会更新。重

7、复执行100次。 实验7.1 代码分析 1、实验目的 了解与文件管理有关的Linux内核模块的代码结构。 2、实验内容 阅读 Linux/Minix中有关文件模块的调用主线,并写出分析报告,包括 l 文件建立模块,即系统调用create() l 文件删除模块,即系统调用rm() l 读/写模块,即 read/write 3、分析报告示例 A. 创建文件模块分析 5780 /*creat system call */ 5781 Creat() 5782 { 5783 resis

8、ter *ip; 5784 extern uchar; 5785 5786 ip = namei(&uchar,1); 5787 if(ip == NULL){ 5788 if(u.u_error) 5789 return; 5790 ip = maknode(u.u_arg[1]&07777&(~ISVTX)); 5791 if (ip == NULL) 5792 return; 5793 open1(ip,FWRITE,2); 5794 }else

9、 5795 open1(ip,FWRITE,1); 5796 } 第5 7 8 6:“namei”( 7 5 1 8 )将一路径名变换成一个“inode”指针。“uchar”是一个过程的名字,它从用户程序数据区一个字符一个字符地取得文件路径名。 5 7 8 7:一个空“inode”指针表示出了一个错,或者并没有具有给定路径名的文件存在。 5 7 8 8:对于出错的各种条件,请见U P M的C R E AT ( I I )。 5 7 9 0:“maknode”( 7 4 5 5 )调用“ialloc”创建一内存“ inode”,然后对其赋初值,并使其进入适当的目录。注意,显式

10、地清除了“粘住”位( I S V T X )。 B. 删除文件rm模块分析 3510 unlink() 3511 { 3512 resister *ip,*pp; 3513 extern uchar; 3514 3515 pp = namei(&uchar,2); 3516 if (pp ==NULL) 3517 return; 3518 prele(pp); 3519 ip = iset(pp ->dev,u.u_dent.u_ino); 3520 if (ip == NULL) 3521 panic (*un

11、link – iset *); 3522 if ((ip ->i_mode%IFMT) == IFDIR && !suser()) 3523 goto out; 3524 u.u_offset[1] = - DIRSIZ+2; 3525 u.ubase = &u.u_dent; 3526 u.ucount = DIRSIZE +2; 3527 u.u_dent.u_ino = 0; 3528 writei(pp); 3529 ip ->i_nlink--; 3530 ip->i_flag =! IUPD; 3531 3532 out:

12、 3533 iput(pp); 3534 iput(ip); 3535 } 新文件作为永久文件自动进入文件目录。关闭文件不会自动地造成文件被删除。当内存“ inode”项中的“ i _ nlink”字段值为0并且相应文件未被打开时,将删除该文件。在创建文件时,该字段由“ m a k n o d e”赋初值为1。系统调用“ link”( 5 9 4 1 )可将其值加1,系统调用“unlink”( 3 5 2 9 )则可将其值减1。创建临时“工作文件”的程序应当在其终止前执行“ unlink”系统调用将这些文件删除。 注意,“unlink”系统调

13、用本身并没有删除文件。当引用计数( i _ count )被减为0时( 7 3 5 0、7 3 6 2 ),才删除该文件。 为了减少在程序或系统崩溃时遗留下来的临时文件所带来的问题,程序员应当遵守下列约定: (1) 在打开临时文件后立即对其执行“ unlink”操作。 (2) 应在“tmp”目录下创建临时文件。在文件名中包括进程标识数就可构成一惟一文件名 C 读/写模块,即 read/write 分析 /* * linux/fs/minix/file.c * * Copyright (C) 1991, 1992 Linus Torvalds * * minix regu

14、lar file handling primitives */ #include #include #include #include #include #include #include #include #include #define NBUF 32 #define MIN(a

15、b) (((a)(b))?(a):(b)) #include #include static int ext2_file_read (struct inode *, struct file *, char *, int); static int ext2_file_write (struct inode *, struct file *, char *, int); static void ext2_release_file (struct inode *, struct file *); /* * We have mostly NULL's here: the current

16、 defaults are ok for * the ext2 filesystem. */ static struct file_operations ext2_file_operations = { NULL, /* lseek - default */ ext2_file_read, /* read */ ext2_file_write, /* write */ NULL, /* readdir - bad */ NULL, /* select - default */ ext2_ioctl, /* ioctl */ generic_mmap, /* mmap */

17、 NULL, /* no special open is needed */ ext2_release_file, /* release */ ext2_sync_file /* fsync */ }; struct inode_operations ext2_file_inode_operations = { &ext2_file_operations,/* default file operations */ NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /

18、 symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ ext2_bmap, /* bmap */ ext2_truncate, /* truncate */ ext2_permission /* permission */ }; static int ext2_file_read (struct inode * inode, struct file * filp,

19、 char * buf, int count) { int read, left, chars; int block, blocks, offset; int bhrequest, uptodate; struct buffer_head ** bhb, ** bhe; struct buffer_head * bhreq[NBUF]; struct buffer_head * buflist[NBUF]; struct super_block * sb; unsigned int size; int err; if (!inode) { printk ("ext2_f

20、ile_read: inode = NULL\n"); return -EINVAL; } sb = inode->i_sb; if (!S_ISREG(inode->i_mode)) { ext2_warning (sb, "ext2_file_read", "mode = %07o", inode->i_mode); return -EINVAL; } offset = filp->f_pos; size = inode->i_size; if (offset > size) left = 0; else left = size - offset; if (l

21、eft > count) left = count; if (left > EXT2_BLOCK_SIZE_BITS(sb); offset &= (sb->s_blocksize - 1); size = (size + sb->s_blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(sb); blocks = (left + offset + sb->s_blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(sb); bhb = bhe = buflist; if (filp->f_reada) { // 37 /* Th

22、is specifies how many sectors to read ahead on the disk. */ // 39 int read_ahead[MAX_BLKDEV] = {0, }; blocks += read_ahead[MAJOR(inode->i_dev)] >> (EXT2_BLOCK_SIZE_BITS(sb) - 9); if (block + blocks > size) blocks = size - block; } /* * We do this in a two stage process. We first try and requ

23、est * as many blocks as we can, then we wait for the first one to * complete, and then we try and wrap up as many as are actually * done. This routine is rather generic, in that it can be used * in a filesystem by substituting the appropriate function in * for getblk * * This routine is optim

24、ized to make maximum use of the various * buffers and caches. */ do { bhrequest = 0; uptodate = 1; while (blocks) { --blocks; *bhb = ext2_getblk (inode, block++, 0, &err); if (*bhb && !(*bhb)->b_uptodate) { uptodate = 0; bhreq[bhrequest++] = *bhb; } if (++bhb == &buflist[NBUF]) bhb = b

25、uflist; /* * If the block we have on hand is uptodate, go ahead * and complete processing */ if (uptodate) break; if (bhb == bhe) break; } /* * Now request them all */ if (bhrequest) ll_rw_block (READ, bhrequest, bhreq); do { /* * Finish off all I/O that has actually completed */

26、if (*bhe) { wait_on_buffer (*bhe); if (!(*bhe)->b_uptodate) { /* read error? */ brelse(*bhe); if (++bhe == &buflist[NBUF]) bhe = buflist; left = 0; break; } } if (left s_blocksize - offset) chars = left; else chars = sb->s_blocksize - offset; filp->f_pos += chars; left -= chars; read

27、 += chars; if (*bhe) { memcpy_tofs (buf, offset + (*bhe)->b_data, chars); brelse (*bhe); buf += chars; } else { while (chars-- > 0) put_fs_byte (0, buf++); } offset = 0; if (++bhe == &buflist[NBUF]) bhe = buflist; } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock)); } while

28、 (left > 0); /* * Release the read-ahead blocks */ while (bhe != bhb) { brelse (*bhe); if (++bhe == &buflist[NBUF]) bhe = buflist; } if (!read) return -EIO; filp->f_reada = 1; if (!IS_RDONLY(inode)) { inode->i_atime = CURRENT_TIME; inode->i_dirt = 1; } return read; } static int ext

29、2_file_write (struct inode * inode, struct file * filp, char * buf, int count) { off_t pos; int written, c; struct buffer_head * bh; char * p; struct super_block * sb; int err; if (!inode) { printk("ext2_file_write: inode = NULL\n"); return -EINVAL; } sb = inode->i_sb; if (sb->s_flags

30、 MS_RDONLY) /* * This fs has been automatically remounted ro because of errors */ return -ENOSPC; if (!S_ISREG(inode->i_mode)) { ext2_warning (sb, "ext2_file_write", "mode = %07o\n", inode->i_mode); return -EINVAL; } /* * ok, append may not work when many processes are writing at the sa

31、me time * but so what. That way leads to madness anyway. */ if (filp->f_flags & O_APPEND) pos = inode->i_size; else pos = filp->f_pos; written = 0; while (written s_blocksize, 1, &err); if (!bh) { if (!written) written = err; break; } c = sb->s_blocksize - (pos % sb->s_blocksize); if

32、c > count-written) c = count - written; if (c != sb->s_blocksize && !bh->b_uptodate) { ll_rw_block (READ, 1, &bh); wait_on_buffer (bh); if (!bh->b_uptodate) { brelse (bh); if (!written) written = -EIO; break; } } p = (pos % sb->s_blocksize) + bh->b_data; pos += c; if (pos > inode->i_s

33、ize) { inode->i_size = pos; inode->i_dirt = 1; } written += c; memcpy_fromfs (p, buf, c); //写入到缓冲块中 buf += c; bh->b_uptodate = 1; bh->b_dirt = 1; brelse (bh); } inode->i_ctime = inode->i_mtime = CURRENT_TIME; filp->f_pos = pos; inode->i_dirt = 1; return written; } 分析: 对于整个文件的索引操作

34、担,都使用块计算的。 整块读取时,调用底层的读取函数。只要得到了更新块就跳出去处理,否则就记录要读取的块 整块的写入时很好办的,只要整体为脏就可以了.但是对于不能整块写入的,必须写入的块原先是更新的. 源码行号 注释: 86 left = size - offset; //剩余可读数 88 left = count; //left就是最终要读取的数据 92 //下面的size和blocks是对于整个文件的索引操作担,都使用块计算的 93 size = (size + sb->s_blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(sb); /

35、/整个文件的块数 94 blocks = (left + offset + sb->s_blocksize - 1) >> EXT2_BLOCK_SIZE_BITS(sb); //要读取的块数 95 bhb = bhe = buflist; 97 //进行预读 98 if (filp->f_reada) { 99 100 // 37 /* This specifies how many sectors to read ahead on the disk. */ 101 // 39 int read_ahead[MAX_BLKDEV] = {0, }; 102 bl

36、ocks += read_ahead[MAJOR(inode->i_dev)] >> 103 (EXT2_BLOCK_SIZE_BITS(sb) - 9); //可能都是使用512标示的,这里进行校正 104 if (block + blocks > size) 105 blocks = size - block; //校正实际能读取的块数 106 } 126 bhreq[bhrequest++] = *bhb; //同时bhrequest记录了需要重新读取的块数 128 if (++bhb == &buflist[NBUF]) //回卷到头部 134 if (up

37、todate) //只要得到了更新块就跳出去处理,否则就记录要读取的块 136 if (bhb == bhe) //满了,要读取NBUF块 142 if (bhrequest) //调用底层的读取函数 150 if (!(*bhe)->b_uptodate) { /* read error? */ //这里当做错误处理的,left=0,跳出大循环了 154 bhe = buflist; //不是跳出去就完了,这里的bhe将来还是有用的 184 while (bhe != bhb) { //预读的块释放掉 191 filp->f_reada = 1; //标志已经预读了 226 if (filp->f_flags & O_APPEND) //是否追加,更新文件指针 237 c = sb->s_blocksize - (pos % sb->s_blocksize); //c记录本次可以读取的字符个数 240 if (c != sb->s_blocksize && !bh->b_uptodate) { //整块的写入时很好办的,只要整体为脏就可以了.但是对于不能整块写入的,必须写入的块原先是更新的. 257 memcpy_fromfs (p, buf, c); //写入到缓冲块中

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服