文档章节

文件句柄、文件描述符与进程和多线程的那些事

Iuranus
 Iuranus
发布于 2014/10/14 11:21
字数 1483
阅读 11736
收藏 14

传送门:PYTHON多线程处理文件

文件句柄(摘抄的一些概念,帮助理解):

句柄是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后返回的是文件对象,至于文件对象的本质,还需要进一步研究。


感谢秦师兄、自习室二期小伙伴们的热烈讨论。

上述内容如果与事实有出入,请一定提出异议。



© 著作权归作者所有

Iuranus
粉丝 12
博文 41
码字总数 22439
作品 0
高级程序员
私信 提问
文件句柄(file handles) & 文件描述符(file descriptors)

1.概述 在实际工作中会经常遇到一些bug,有些就需要用到文件句柄,文件描述符等概念,比如报错: too many open files, 如果你对相关知识一无所知,那么debug起来将会异常痛苦。在linux操作系...

u013256816
2017/03/07
0
0
IO多路复用的三种机制Select,Poll,Epoll

I/O多路复用(multiplexing)的本质是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操...

阳光的记忆
2018/05/14
0
0
Linux 文件句柄的这些技术内幕,只有 1% 的人知道

1. 缘起 某个月朗风清的晚上,正在公司对面的深大操场跑步,突然接到同事发来的消息,他发现某机器上的文件句柄使用量有十一万多个(下面输出中的第一个字段) 但是通过运维常用的lsof命令算...

技术小能手
2018/07/24
0
0
file-max VS ulimit

简单的说, max-file表示系统级别的能够打开的文件句柄的数量, 而ulimit -n控制进程级别能够打开的文件句柄的数量. file-max中指定了系统范围内所有进程可打开的文件句柄的数量限制(系统级别,...

China_OS
2012/02/04
0
0
Linux-什么是文件描述符以及相关应用

博文说明【前言】: 本文将通过个人口吻介绍通过Linux中的文件描述符相关知识,在目前时间点【2017年7月4号】下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大家指出问...

1清风揽月1
2017/07/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

面试题:你简历中写到熟悉Spring源码,那你给我说说它用到了那些设计模式?

Spring作为业界的经典框架,无论是在架构设计方面,还是在代码编写方面,都堪称行内典范。好了,话不多说,开始今天的内容。 spring中常用的设计模式达到九种。 模板方法(Template Method)...

我最喜欢三大框架
15分钟前
1
0
Sentinel Dashboard中修改规则同步到Nacos

上一篇我们介绍了如何通过改造Sentinel Dashboard来实现修改规则之后自动同步到Apollo。下面通过这篇,详细介绍当使用Nacos作为配置中心之后,如何实现Sentinel Dashboard中修改规则同步到N...

程序猿DD
22分钟前
4
0
Jenkins发送测试报告邮件

简介:总结怎么使用Jenkins执行自动化测试后发送测试报告邮件 一、系统设置 1、在Jenkins安装Email Extension Plugin插件,如下图: 2、设置Extended E-mail Notification (1)进入“系统管理”...

shzwork
25分钟前
1
0
状态模式

//相当把一个State对象存到Context对象中,然后通过Context实例化对象调用保存的state对象去调用state的相应的方法 https://blog.csdn.net/syc434432458/article/details/51210361...

南桥北木
36分钟前
3
0
基于 Jenkins + JaCoCo 实现功能测试代码覆盖率统计

本文首发于:Jenkins 中文社区 使用 JaCoCo 统计功能测试代码覆盖率? 对于 JaCoCo,有所了解但又不是很熟悉。 "有所了解"指的是在 CI 实践中已经使用 JaCoCo 对单元测试代码覆盖率统计: 当...

Jenkins中文社区
44分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部