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

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

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

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

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

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

句柄是操做系统在生成对象时分配给对象的惟一标识。 经过句柄能够获取操做系统提供的服务。句柄不一样于指针,若是你获得一个对象的指针,那你就能够在此对象上随心所欲了。因而系统不给你指针,而给用户一个加了限制的,用于跟踪对象的指针的标识——句柄。系统使用句柄向外提供服务就相对安全了。
spa

总结:操作系统

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

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

三、关于在进程、线程下,这个时候用文件句柄很差阐述,能够把文件句柄理解成下图中的文件描述符,以下图:指针


每一个进程有各自独立的文件描述符,打开不一样的文件也都会有不一样的打开文件表,而且指向不一样的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后返回的是文件对象,至于文件对象的本质,还须要进一步研究。


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

上述内容若是与事实有出入,请必定提出异议。


相关文章
相关标签/搜索