Linux操做系統進程與文件的關係

本文重點介紹一下Linux操做系統進程(線程)與文件描述符、文件的關係,具體到內核部分就是task_struct、files_struct、file和inode的關係。node

咱們在Linux用戶態開發都清楚,打開一個文件以後會返回一個文件描述符,並且每一個進程打開文件的數量是有限的。這個具體是什麼什麼緣由?數組

若是咱們深刻到Linux操做系統的內核,就會知道其中的奧祕。在Linux操做系統,每一個用戶態的進程在內核態都有一個對應的內核進程(線程),這個在內核中經過task_struct結構體標識,內核經過其實現對進程的調度。而在內核中對於文件的訪問則是經過file和inode結構體實現的,其中包含這訪問文件的關鍵信息(例如訪問偏移)和方法(例如讀寫文件操做)。操作系統

fd=open(「/home/zhf/zhf/c_prj/itworld123.com」,O_RDWR);線程

進程與文件的關係

以下圖是典型的進程與文件的關係圖,圖中進程打開了兩個不一樣的文件。在進程結構體(task_struct)中有一個files_struct成員,其中保存這一個數組,這個數組的偏移量就是文件描述符,而其中的成員則是file結構體的指針。這樣,經過用戶態的整型的文件描述符能夠很方便的找到管理文件的結構體(file)進而實現對文件的操做。本文爲了方便說明,對files_struct結構體進行了簡化處理,實際上該結構提要複雜不少。3d

圖1 單進程概圖

進程(task_struct)與文件結構體(file)的關係清楚了,那麼文件結構體又是怎麼來的,它跟inode的關係是什麼樣的呢?如上圖所示,每個file都有一個對應的inode的結構體。兩種其實都對應着一個磁盤上的具體文件,但又有差別。file其實對應這一個打開文件的實例,而inode一一對應一個磁盤文件。也就是說一個磁盤文件對應的file在內存中可能有多份,而inode則只會有一份。後續咱們會詳細解釋具體實現。指針

父子進程與文件的關係

咱們知道在Linux中進程都存在一些父子關係,並且子進程會繼承父進程的不少內容。那麼若是咱們fork出一個子進程,此時子進程會繼承父進程文件相關的內容。若是咱們使用的是fork系統調用,此時子進程會建立一個新的files_struct實例,並將父進程的內容遷移過來,這裏說遷移,而不是拷貝,其緣由是並非原封不懂的內存拷貝,而是會作一些處理。好比父進程中對file結構體的指向,在子進程中也會指向,且文件描述符一致,同時會增長file結構體實例的引用計數,確保使用關係的正確性。 cdn

還有一種狀況,Linux操做系統提供了另一種建立子進程的方法,也就是clone方法。經過該方法建立進程時能夠指定子進程能夠不繼承父進程的那些內容。若是此時傳入了CLONE_FILES參數,則不會進行files_struct結構體的遷移,而只是增長一個該結構體的引用計數。也就是父進程和子進程中的files指針指向相同的內存區域,此時整個關係以下圖所示。

圖3 進程clone關係圖

先到這裏,後續本文會繼續討論file結構體與inode及磁盤數據的關係。blog

相關文章
相關標籤/搜索