

免费预览已结束,剩余16页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
高级系统程序设计重庆科技学院高级系统程序设计大作业专业班级: 学 号: 姓 名: 成 绩: 摘 要在windows api中,有自己独特的i/o操作,与c/c+中的i/o操作有何种区别;并且windows中的内核对象是怎样定义的,具体是怎样操作。windows有自己的内存架构,根据特定的要求有不同的管理内存方法,其中堆适合大量的小对象,然而内存映射文件适合大文件,各自具有不同的特性。关键字:i/o 内核对象 堆 内存映射文件目 录公共部分11.1请综合比较c/c+中i/o的使用方法与本课程程序实践中所采用的i/o方法各自的特点,并请举例分析说明?11.1.1 c/c+ i/o11.1.2windows i/o21.1.3总体区别31.2基本请结合具体的例子解释什么是内核对象,对内核对象的操作与之前学习的对指针的操作方法有什么本质的区别?31.2.1windows中的内核对象31.2.2内核对象与指针的区别4选题部分52.1windows内存管理构架52.2内存映射文件52.2.1怎样使用内存映射文件52.2.2内存映射文件的使用特点62.3堆92.3.1使用堆92.3.2堆的使用特点103.总结12参考文献13致谢1415公共部分1.1请综合比较c/c+中i/o的使用方法与本课程程序实践中所采用的i/o方法各自的特点,并请举例分析说明?1.1.1 c/c+ i/o1)用标准库,通过调用函数实现标准输入,输出c/c+的输入/输出由标准库提供。标准库定义了一族类型,支持对文件和控制窗口等设备的读写。而且在c+中还新定义了i/o流,在c语言中,标准库stdio.h提供了两个控制台格式化输入、输出函数printf()和scanf(),这两个函数可以在标准输入输出设备上以各种不同的格式读写数据。printf()函数用来向标准输出设备(屏幕)写数据,具体格式为printf(,);scanf()函数用来从标准输入,具体格式为:scanf(,);例如:输入:printf(”hahahahahan”);输出:scanf(“%d”,&a);在c+中,i/o流是一系列写到屏幕上或从键盘上读出的字节序列。将i/o流定义为类,执行标准的输入输出操作时,一般使用i/o流cin作为输入,cout作为输出。在ios.h、iostream.h、istream.h、ostream.h以及streamb.h中可以找到i/o流的定义。iostream.h中定义了如下四个对象:cin键盘输入(stdin)、cout屏幕输出(stdout)、cerr标准错误设备输出(stderr)、clog标准错误缓冲输出(stderr)。例如:cinname;cout”helllo world!”;cerr”error!”;clog 0) writefile (hout, buffer, nin, &nout, null);关闭文件句柄closehandle (hin); closehandle (hout);1.2.2内核对象与指针的区别实例中,文件对象是windows中的内核对象,我们只能调用windows提供的api函数进行文件操作,事实上我们也只能通过文件句柄进行操作,除此之外没有其它的办法。但是在c/c+中,将对象的地址作为数据,也就是指针值,用于保存地址的变量就是指针。也就是通过指针访问内存,进行内存中数据的修改。我们只要知道了内存地址,就可以通过指针对该内存进行修改。然而windows中的内核对象,我们只能通过api函数,得到句柄进行相关的操作而且windows中为了对象的安全,支持广泛的安全模型,能够防止对诸如文件、进程等对象的未经授权的访问,其中几乎所有可共享的对象都可以得到保护。例如:windows中,在创建文件时,第四个参数,lpsecurity_attributes lpsecurityattributes,就是说明了对象的安全属性。所以,指针与内核对象的本质区别就是,指针可以对内存进行任意的修改,而且指针可以我们根据自己的需要进行定义。内核对象只能通过句柄对相关的地方进行操作,而且有严格的对象安全属性,只能根据需要调用api函数,不能自己定义!选题部分题目一:综合比较windows内存管理中内存映射文件和堆2钟方法各自的特点,写出你的详细分析结论并请编程举例说明,必须在大作业中给出你的每个程序的设计思考过程和关键程序代码段,完整的源程序可在附录中给出。 2.1windows内存管理构架 windows程序c库:malloc,free mmf api (内存映射文件) 堆api 虚拟内存api 带有虚拟内存管理器的windows内核物理内存磁盘和文件系统2.2内存映射文件内存映射文件的物理存储器来自磁盘上已有的文件,而不是来自系统的页面交换文件,一旦把文件映射到地址空间,我们就可以对他进行访问,就好像将整个文件已经载入内存一样。2.2.1怎样使用内存映射文件1)打开文件2)如果是新文件,那么要使用createfilemapping,要么先使用setfilepointerex,然后使用setendoffile来设置长度。3) 使用createfilemapping或openfilemapping来映射文件4) 使用mapviewofile创建一个或多个视图5) 通过内存引用来访问文件6)完成后,关闭有关句柄涉及的有关函数:创建一个带有句柄的文件映射对象handle createfilemapping(handle hfile, /物理文件句柄lpsecurity_attributes lpsa, /安全设置dword dwprotect, /保护设置dword dwmaximumsizehigh, /高位文件大小dword dwmaximumsizelow, /低位文件大小lpctstr lpmapname /共享内存名称);打开现有的文件映射:handle openfilemapping(dword dwdesiredaccess,/访问权限bool binherithandle,/ 返回的句柄是否能由当前进程启动的新进程继承lpctstr lpmaname/共享内存名称)将对象映射到地址空间lpvoid mapviewoffile( handlehmapobject,/ 文件映射对象的句柄 dworddwaccess,/访问权限 dworddwoffsethigh,/ 文件中映射起点的高32位地址dworddwoffsetlow,/文件中映射起点的低32位地址 size_t cbmap/以字节为单位的映射区域尺寸值);关闭映射句柄bool unmapviewoffile(lpvoid lpbaseaddress)2.2.2内存映射文件的使用特点1)系统使用内存映射文件,以便加载和执行.exe和dll文件。大大节省页文件空间和应用程序启动运行所需的时间。当一个程序在调用createprocess的时候,系统首先就会先确定创建进程时所指定的可执行文件的位置,如果找不到创建进程就会失败;找到了可执行文件的位置,系统就会创建一个新的进程内核对象,并为他创建一个私有的地址空间。而且系统会预定一块足够大的地址空间来容纳可执行文件并且系统会对地址空间区域进行标注说明该区域来自磁盘上的可执行文件,也就是将可执行文件映射到虚拟地址空间,这样就可以节省页文件空间。当系统把可执行文件映射到进程的地址空间后,就会访问可执行文件中一个段,这个段列出了一些dll文件,他们包含了可执行文件的需要调用的函数。同样系统会把用到的dll也映射到一块足够大的地址空间并标注。把所有的可执行文件和dll文件都映射到进程的地址空间后,系统就会开始执行可执行文件的启动代码。由于采取的文件映射,时间较短,就不用一段一段的将指令读入内存,所以也就节省了程序的启动运行时间。2)开发人员使用内存映射文件来访问磁盘上的数据文件。这样可以避免直接对文件执行i/o操作和对文件内容进行缓存,并且可以进行大文件操作。由于使用内存映射文件,是将来自磁盘上已有的文件映射到地址空间,所以肯定就可以避免直接对文件执行i/o操作和对文件内容进行缓存。例如:将一个文件映射到虚拟内存空间handle hfile = invalid_handle_value, hmap = null;lpvoid pfile = null;hfile = createfile (tempfile, generic_read| generic_write, 0, null, open_existing, 0, null);/打开文件hmap = createfilemapping (hfile, null, page_readwrite, 0, 0, null);/创建一个内核文件映射对象pfile = mapviewoffile (hmap, file_map_all_access, 0, 0, 0);/将文件映射到进程的虚拟地址空间unmapviewoffile (pfile)/释放视图;closehandle (hmap);/关闭文件映射句柄closehandle (hfile);/关闭文件句柄在win32 api中,提供有支持文件处理的函数 (如createfile()、writefile()、readfile()等).。一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些超过几个g大文件,再以通常的文件处理方法进行处理显然是行不通的,因为不能一次将文件映像全部映射进来。对于这种情况只能依次将大文件的各个部分映射到进程中的一个较小的地址空间例如:使用内存映射文件进行大文件的操作,由于不能一次性将文件全部映射到地址空间,所以就只能将文件一部分一部分的映射到地址空间,其中最关键的是要分别将每一部分映射到地址空间后,要关闭视图,而且要确定文件偏移的大小,循环映射,直到文件全部映射完成(本程序源于wndows核心编程第五版)/创建文件handlehfile=createfile(“haha”,generic_read|generic_write,0,null,open_existing,file_attribute_normal,null);/创建文件映射handlehfilemap=createfilemapping(hfile,null,page_readwrite,0,0,null);/得到系统分配粒度system_infosysinfo;getsysteminfo(&sysinfo);dworddwgran=sysinfo.dwallocationgranularity;/得到文件尺寸dworddwfilesizehigh;_int64qwfilesize=getfilesize(hfile,&dwfilesizehigh);qwfilesize|=(_int64)dwfilesizehigh)32);/关闭文件对象closehandle(hfile);/偏移地址_int64qwfileoffset=0;/块大小dworddwblockbytes=1000*dwgran;if(qwfilesize0)/映射视图lpbytelpbmapaddress=(lpbyte)mapviewoffile(hfilemap,file_map_all_access,(dword)(qwfileoffset32),(dword)(qwfileoffset&0xffffffff),dwblockbytes);/对映射的视图进行访问for(dwordi=0;idwblockbytes;i+)bytetemp=*(lpbmapaddress+i);/撤消文件映像unmapviewoffile(lpbmapaddress);/修正参数qwfileoffset+=dwblockbytes;qwfilesize-=dwblockbytes;/关闭文件映射对象句柄closehandle(hfilemap);3)可以使用内存映射文件,使同一台计算机上运行的多个进程能够相互之间共享数据共享内存主要是通过映射机制实现的。windows下进程的地址空间是相互隔离的,但在物理上却是重叠的。所谓的重叠是指同一块内存区域可能被多个进程同时使用。当调用createfilemapping创建命名的内存映射文件对象时,windows即在物理内存中申请了一块指定大小的内存区域,返回文件映射对象的新句柄hmap。为了能够访问这块区域必须调mapviewofifile函数,促使windows将此内存空间映射到进程的地址空间中。当在其他进程中访问这块区域时,则必须使用openfilemapping函数来取得对象句柄hmap,并调用mapviewoffile函数得到此内存空间的一个映射。这样一来,系统就把同一块内存区域映射到了不同进程的地址空间中,从而达到共享内存的目的。例如:用c写一个程序,使用内存映射文件进行简单的数据共享。首先,将字符串利用内存映射文件映射到地址空间char name = sure; / 内存映射对象的名称 char data = abcdefghijk; / 共享内存中的数据 lpvoid pbuffer; / 共享内存指针 handle hmap=createfilemapping( invalid_handle_value,nupage_readwrite,0, strlen(data),name); / 映射对象的一个视图,得到指向共享内存的指针,设置里面的数据 pbuffer = mapviewoffile(hmap, file_map_all_access, 0, 0, 0); strcpy(char*)pbuffer, data); printf( 写入共享内存数据:%sn, (char*)pbuffer); 然后,打开现有的文件映射使用openfilemapping函数来取得对象句柄hin,并调用mapviewoffile函数得到此内存空间的一个映射 handle hin=openfilemapping(file_map_all_access, 0, name); if(hin != null) / 打开成功,映射对象的一个视图,得到指向共享内存的指针,显示出里面的数据 pbuffer =mapviewoffile(hin, file_map_all_access, 0, 0, 0); printf( 读出共享内存数据:%sn, (char*)pbuffer); 2.3堆windows在堆中维护着内存池,进程可以包含许多堆,我们从堆中分配内存。而且堆是windows对象,但不是内核对象,在分配内存时需要堆句柄。 堆是进程创建时在进程空间建立的区域,由堆管理器来管理。一个进程可以有很多个堆。进程有一个默认堆,可以动态的扩大。当程序需要管理很多小对象时,适合用堆。2.3.1使用堆一、使用堆常用的函数:1、 获得进程默认堆句柄handle getprocessheap(void)返回:本进程的堆句柄,失败返回null2、 创建堆handle heapcreate( dword floptions,/创建堆的选项 dword dwinitialsize,/初始大小 dword dwmaximumsize/最大尺寸)3、从堆中分配内存块 heapalloclpvoidheapalloc(handle hheap;/分配内存的堆句柄dword dwflags;/分配控制的选项size_t dwbytes/分配内存块的大小) 4、 改变内存块的大小 heaprealloclpvoid heaprealloc(handle hheap;/修改堆的句柄dword dwflags;/控制选项lpvoid lpmem;/指定重新分配的内存块size_t dwbytes/新块的大小); 5、释放内存块 heapfree bool heapfree(handle hheap;/释放堆的句柄dword dwflags;/控制选项lpvoid lpmem;/指定释放的内存块);6、得到堆的尺寸heapsize size_t heapsize(handle hheap,/堆句柄dword dwflags,/唯一可能的值是heap_no_serializelpcvoid lpmem/指定的内存块)7、 撤销堆 heapdestroybool heapdestroy(handle hheap);2.3.2堆的使用特点1、用来分配许多较小的数据块,可不考虑分配粒度和页面边界。在堆管理中,有堆管理器来替它管理,不需管理具体的事情如页面边界和分配粒度等问题。堆成功创建以后, 整个堆的构造如图2所示, 堆是以堆管理结构开始的,图中的初始区域是参数 dwinitialsize指定的。暂时未用的保留区域(预备区域), 它和初始区域的总和由参数dwmaximumsize指定。 初始区域管理结构 预备区域 图2 堆的结构保留区域中的多数页面并没有提交到物理存储器。 随着从堆中越来越多地进行内存分配, 堆管理器逐渐把更多的物理存储器提交给堆。堆的物理存储器从系统页文件中分配, 在释放时有专门的堆管理器负责对已占用物理存储器的回收。 应用程序可以使用系统提供的一系列函数来创建自己的堆并对堆中的内存进行管理, 主要包括堆内存块的分配和堆内存块的释放, 以及堆内存块的枚举、 计算内存块的大小等等。堆用来分配较小的数据块,也就是说,适合管理大量的小对象。比如,用来管理链表和二叉树。例如:使用堆,实现二叉排序数,实现动态分配内存在程序中使用两个堆,在二叉树的每个结点中,包含了左指针、右指针、一个键以及一个指向数据堆中的数据记录指针。定义如下:typedef struct _treenode struct _treenode *left, *right;/ 左指针、右指针tchar keykey_size;/ 键lptstr pdata;/ 指向数据堆中的数据记录指针 treenode, *lptnode, *lpptnode;其中,键保存在结点堆(node heap)中,节点堆的定义如下:hnode=heapcreate(heap_generate_exceptions|heap_no_serialize,node_heap_isize, 0);数据堆(data heap)定义如下;hdata=heapcreate(heap_generate_exceptions|heap_no_serialize,data_heap_isize, 0);为两个堆分配内存pnode = heapalloc (hnode, heap_zero_memory, node_size);pstring = heapalloc (hdata, heap_zero_memory,(size_t)(key_size + _tcslen (datahold) + 1) * tsize); 2、系统在进程的地址空间创建(默认)堆(1m),对默认堆的访问是顺序进行的。创建应用程序时可改变默认区域大小,不能撤销进程的默认堆。widows 中,每个进程有一个缺省堆,这种堆是进程创建时,由系统创建的堆。默认时,该堆的大小是1mb,可以通过链接器开关/heap来修改缺省堆大小。系统在任一时刻只能有一个线程在缺省堆中分配或释放内存块。每一个堆都有它自己的句柄可以使用getprocessheap函数来获得缺省堆句柄。进程默认堆是供所有线程使用的,每当线程需要从堆中分配释放内存区时,系统会同步堆,所以访问
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年新能源商用车型号解析:市场需求与应用场景深度分析报告
- 2025年房地产市场区域分化对投资策略的适应性研究报告
- 2025年实体书店在数字化营销中的转型策略研究报告
- 2025至2030年中国横鱼行业发展潜力分析及投资方向研究报告
- 解析卷-北师大版8年级数学上册期末试题及完整答案详解【典优】
- 解析卷北师大版9年级数学上册期中试题附答案详解(A卷)
- 2025年贷款利率变动委托管理合同范本
- 2025版人工智能语音助手授权委托协议
- 2025年度高新技术项目居间对接服务协议
- 2025年度化工原料采购协议
- 数智化保障核燃料供应-2025 中核建中核燃料元件有限公司
- 幼儿体能教学课件下载
- 《沉积岩与沉积相》地质资源勘查工程专业全套教学课件
- 江苏省常州市2025年初中地理学业水平考试真题(含答案)
- 猪场员工安全培训课件
- QGDW10364-2020单相智能电能表技术规范
- 颅内感染解读
- (高清版)DB31∕T 1550-2025 动物无害化处理场所生物安全技术规范
- 2025至2030中国农资连锁超市行业发展趋势分析与未来投资战略咨询研究报告
- QGDW11447-202410kV-500kV输变电设备交接试验规程
- 肺栓塞的中医护理
评论
0/150
提交评论