• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            攀升·Uranus


            Something Different,Something New
            數(shù)據(jù)加載中……

            (轉(zhuǎn))UNIX IO---再談文件描述符

            在C程序中,文件由文件指針或者文件描述符表示。ISO C的標準I/0庫函數(shù)(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指針,UNIX的I/O函數(shù)(open, close, read, write, ioctl)使用文件描述符。下面重點來說下,文件描述符是如何工作的。
             
            文件描述符相當(dāng)于一個邏輯句柄,而open,close等函數(shù)則是將文件或者物理設(shè)備與句柄相關(guān)聯(lián)。句柄是一個整數(shù),可以理解為進程特定的文件 描述符表的索引。先介紹下面三個概念,后面講下open、close等操作以后,文件和文件描述符產(chǎn)生什么關(guān)系,以及fork后文件描述符的繼承等問題。
             
            文件描述符表 :用戶區(qū)的一部分,除非通過使用文件描述符的函數(shù),否則程序無法對其進行訪問。對進程中每個打開的文件,文件描述符表都包含一個條目。
             
            系統(tǒng)文件表 :為系統(tǒng)中所有的進程共享。對每個活動的open, 它都包含一個條目。每個系統(tǒng)文件表的條目都包含文件偏移量、訪問模式(讀、寫、or 讀-寫)以及指向它的文件描述符表的條目計數(shù)。
             
            內(nèi)存索引節(jié)點表: 對系統(tǒng)中的每個活動的文件(被某個進程打開了),內(nèi)存中索引節(jié)點表都包含一個條目。幾個系統(tǒng)文件表條目可能對應(yīng)于同一個內(nèi)存索引節(jié)點表(不同進程打開同一個文件)。
             
            1、舉例: 執(zhí)行myfd = open( "/home/lucy/my.dat", O_RDONLY); 以后,上述3個表的關(guān)系原理圖如下:
            http://keren.blog.51cto.com/
                                                                                              圖1
             
            系統(tǒng)文件表包含一個偏移量,給出了文件當(dāng)前的位置。若2個進程同時打開一個文件(如上圖A,B)做讀操作,每個進程都有自己相對于文件的偏移 量,而且讀入整個文件是獨立于另一個進程的;如果2個進程打開同一個文件做寫操作,寫操作是相互獨立的,每個進程都可以重寫另一個進程寫入的內(nèi)容。
             
            如果上面進程在open以后又執(zhí)行了close()函數(shù),操作系統(tǒng)會刪除文件描述符表的第四個條目,和系統(tǒng)文件表的對應(yīng)條目(若指向它的描述符 表唯一),并對內(nèi)存索引節(jié)點表條目中的計數(shù)減1,如果自減以后變?yōu)?,說明沒有其他進程鏈接此文件,將索引節(jié)點表條目也刪除,而這里進程B也在open這 個文件,所以索引節(jié)點表條目保留。
             
            2、文件描述符的繼承
            通過fork()創(chuàng)建子進程時,子進程繼承父進程環(huán)境和上下文的大部分內(nèi)容的拷貝,其中就包括文件描述符表。
             
            (1)對于父進程在fork()之前打開的文件來說,子進程都會繼承,與父進程共享相同的文件偏移量。如下圖所示(0-1-2 表示 標準輸入-輸出-錯誤):
                                              圖2 fork()之前打開my.dat
             
            系統(tǒng)文件表位于系統(tǒng)空間中,不會被fork()復(fù)制,但是系統(tǒng)文件表中的條目會保存指向它的文件描述符表的計數(shù),fork()時需要對這個計數(shù) 進行維護,以體現(xiàn)子進程對應(yīng)的新的文件描述符表也指向它。程序關(guān)閉文件時,也是將系統(tǒng)文件表條目內(nèi)部的計數(shù)減一,當(dāng)計數(shù)值減為0時,才將其刪除。
             
            (2)相反,如果父進程先進程fork,再打開my.dat,這時父子進程關(guān)于my.dat 的文件描述符表指向不同的系統(tǒng)文件表條目,也不再共享文件偏移量(fork以后2個進程分別open,在系統(tǒng)文件表中創(chuàng)建2個條目);但是關(guān)于標準輸入, 標準輸出,標準錯誤,父子進程還是共享的。
                                  圖3   fork()以后打開my.dat
             
             

            本文出自 “淡泊明志,寧靜致遠” 博客,請務(wù)必保留此出處http://keren.blog.51cto.com/720558/170822


            posted on 2009-12-22 11:20 攀升 閱讀(706) 評論(0)  編輯 收藏 引用 所屬分類: Linux

            亚洲乱码日产精品a级毛片久久| 国产激情久久久久久熟女老人| 97久久精品人妻人人搡人人玩| 久久不见久久见免费视频7| 69国产成人综合久久精品| 久久精品国产精品亚洲| 亚洲综合精品香蕉久久网| 91精品免费久久久久久久久| 国内精品综合久久久40p| 亚洲国产精品一区二区久久| 久久精品国产亚洲AV香蕉| 91久久九九无码成人网站| 99久久精品免费看国产一区二区三区 | 久久精品九九亚洲精品| 狠狠狠色丁香婷婷综合久久俺| 久久综合综合久久狠狠狠97色88| 久久久久亚洲精品男人的天堂| 久久精品无码专区免费青青| 欧美无乱码久久久免费午夜一区二区三区中文字幕| 欧美日韩精品久久免费| 蜜臀久久99精品久久久久久 | 久久精品无码专区免费| 久久久久久久人妻无码中文字幕爆| 丰满少妇人妻久久久久久4| 久久一日本道色综合久久| 久久久久久久女国产乱让韩| 久久精品亚洲乱码伦伦中文| 久久精品国产亚洲AV高清热 | 久久99热只有频精品8| 久久久久久A亚洲欧洲AV冫| 韩国三级中文字幕hd久久精品| 久久婷婷色综合一区二区| 国产精品一久久香蕉国产线看观看 | 久久国产高潮流白浆免费观看| 性做久久久久久久久久久| 久久久久国产日韩精品网站| 久久高清一级毛片| 热久久视久久精品18| 久久人妻AV中文字幕| 久久午夜羞羞影院免费观看| 少妇久久久久久久久久|