文件句柄

文件句柄

句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。

如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?

为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。

句柄是操作系统在生成对象时分配给对象的唯一标识。 通过句柄可以获取操作系统提供的服务。句柄不同于指针,如果你得到一个对象的指针,那你就可以在此对象上为所欲为了。于是系统不给你指针,而给用户一个加了限制的,用于跟踪对象的指针的标识——句柄。系统使用句柄向外提供服务就相对安全了。

总结:

1、无论是文件句柄(Windows中概念),还是文件描述符(linux中概念),其最终目的都是用来定位打开的文件在内存中的位置,只是它们映射的方式不一样。

2、文件句柄定位到的是文件对象,而非文件。而文件对象是对这个文件的一些状态、属性的封装,例如读取到的文件位置等。

3、关于在进程、线程下,这个时候用文件句柄不好阐述,可以把文件句柄理解成下图中的文件描述符,如下图:

每个进程有各自独立的文件描述符,打开不同的文件也都会有不同的打开文件表项,并且指向不同的v-node表项。

此时没有共享文件,并且每个描述符对应一个不同的文件。

不同的进程多次open一个文件,则会产生不同的打开文件表项,但最终指向的是同一个文件的v-node标项。

此时,多个描述符也可以通过不同的文件表表项来引用同一个文件。例如,如果以同一个filename调用open函数两次,就会发生这种情况。关键思想是:每个描述符都有它自己的文件位置,所以对不同描述符的读操作可以从文件的不同位置获取数据。

如果在多线程中打开同一个文件(不同于在主线程中打开一个文件,并将fd=open(file)的fd参数传给线程),则每个线程会有各自的文件描述符,按照上一条关键思想,这每个线程也会有保存自己的读取位置,互不影响。

深入理解计算机系统里还有这么段话:因为每个进程都有自己HANDLE的存储空间);如果是同一个进程的线程,因为同基于I/O多路复用的流一样,多个线程运行在单一进程的上下文中,共享这个进程虚拟地址空间的整个内容,包括它的代码、数据、堆、共享库和打开的文件(句柄)。这个应该也是指的进程已经打开文件,则线程共享打开的文件。

 

如果在调用fork之前父进程已经打开文件,则fork后子进程有一个父进程描述符表的副本。父子进程共享相同的打开文件集合,因此共享相同的文件位置。

这个情况跟主线程已经open文件,并把fd传给启动的线程的情况是一样的。

 

另外关注上述图片表的解释如下:


这下清楚不少,但是昨天关于Python中myFile = open(‘fileLoc‘,‘r‘)的情况还不能照搬理解,因为Python的封装,open后返回的是文件对象,至于文件对象的本质,还需要进一步研究。

时间: 2024-10-13 18:24:55

文件句柄的相关文章

linux文件句柄

在linux中执行ulimit -a 即可查询linux相关的参数,默认情况下,linux最大文件句柄数为1024个.当你的服务器在大并发达到极限时,就会报出"too many open files". [[email protected] ~]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (block

iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄

前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传.    在实际开发中,输入输出流用的比较少,但是用起来也是很方便的.iOS开发用到的输入输出流和在Java中的输入输出流是几乎一样的,本质也是一个意思:将网络返回的数据当做流来处理.    输入输出的理解:输入到哪里?输出到哪里?这个问题不难理解,输入输出是要站着服务器角度来思考的,下面用图来解释:    代码关键词: 1.在接收到响应头的代理

ios开发网络学习十:利用文件句柄实现大文件下载

#import "ViewController.h" @interface ViewController ()<NSURLSessionDataDelegate> @property (weak, nonatomic) IBOutlet UIProgressView *proessView; /** 接受响应体信息 */ @property (nonatomic, strong) NSFileHandle *handle; @property (nonatomic, ass

设置Linux打开文件句柄/proc/sys/fs/file-max和ulimit -n的区别

max-file 表示系统级别的能够打开的文件句柄的数量.是对整个系统的限制,并不是针对用户的. ulimit -n 控制进程级别能够打开的文件句柄的数量.提供对shell及其启动的进程的可用文件句柄的控制.这是进程级别的. 对于服务器来说,file-max和ulimit都需要设置,否则会出现文件描述符耗尽的问题. 一般如果遇到文件句柄达到上限时,会碰到"Too many open files"或者Socket/File: Can't open so many files等错误. 为了

select.select()文件句柄的限制

摘要 python中的select.select()函数调用了系统底层的select(),但是他有一个限制,就是当打开的文件句柄的数字达到1024后,就会出现下面的错误 ValueError: filedescriptor out of range in select() 正文 这个值在select()中对应的是FD_SETSIZE,下面我们写一段脚步来证明 #!/usr/bin/env python import subprocess import os import select impor

Chromium中跨进程文件句柄传递

实现说明 在Chromium跨进程架构下,也会有Browser/Renderer两个进程对相同文件进行操作的需求.比如Browser的某个任务依赖于Renderer端对指定文件的输出.而在POXIS下,允许不同进程间传递文件描述符(File Descriptor))的, 比如传递socket,或者普通文件,进而可以达到不需要重新打开文件,而对相同文件读写的效果(并不是分享文件句柄).Chromium对这个特性做了封装,也包括了Windows下的实现(也包括了Windows下的实现).涉及的基本结

linux最大文件句柄数量总结(转载)

最近部署上线的一个引擎,启动之后内存.日志显示一切正常,但是外部无法进行引擎访问.几经周折,在同事的协助下,找出了问题:root用户的open files为1024,引擎启动时,1024个文件句柄已经用尽.在晚上看到一篇不错的文章,就转下来了:http://jameswxx.iteye.com/blog/2096461.以下是文章内容: 写这个文章是为了以正视听,网上的文章人云亦云到简直令人发指.到底最大文件数被什么限制了?too many open files错误到底可以通过什么参数控制?网上

Linux中如何解除最大进程数和最大文件句柄打开数限制?

本文和大家分享的主要是linux中解除最大进程数和最大文件句柄打开数限制相关内容,一起来看看吧,希望对大家学习linux有所帮助. ulimit用于shell启动进程所占用的资源 1.语法格式: ulimit [-acdfHlmnpsStvw] [size] 2.参数介绍: -H 设置硬件资源限制. -S 设置软件资源限制. -a 显示当前所有的资源限制. -c size:设置core文件的最大值.单位:blocks -d size:设置数据段的最大值.单位:kbytes -f size:设置创

修改Linux系统参数以支持单机同时打开数百万文件句柄

在linux kernel 2.6.25之前通过ulimit -n(setrlimit(RLIMIT_NOFILE))设置每个进程的最大打开文件句柄数不能超过NR_OPEN (1024*1024),也就是100多w(除非重新编译内核),而在2.6.25之后,内核导出了一个sys接口可以修改这个最大值(/proc/sys/fs /nr_open). 具体的changelog: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi

perl 文件句柄DATA

1 #!/usr/bin/perl 2 3 while (<DATA>) { 4 print; 5 } 6 7 __DATA__ 8 hello perl 输出结果: hello perl 这个用法太方便太perl了,以后再也不需要使用新建文件的笨方法了. 下面是解释: <IN>可以从打开的句柄IN中获得数据,<STDIN>可以从标准输入接收数据,类似地,<DATA> 文件句柄可以直接从执行它的脚本中获取数据,而不是从命令行或者从另一个文件里获取.<D