新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > linux基礎復習(6)文件I/O操作

        linux基礎復習(6)文件I/O操作

        作者: 時間:2016-10-08 來源:網絡 收藏

        上鎖,也就是記錄鎖。記錄鎖又可分為讀取鎖和寫入鎖,其中讀取鎖又稱為共享鎖,它能夠使多個進程都能在

        文件的同一部分建立讀取鎖。而寫入鎖又稱為排斥鎖,在任何時刻只能有一個進程在文件的某個部分上建立寫入鎖。當然,在文件的同一部分不能同時建立讀取鎖和寫入鎖。

        fcntl函數格式

        fcntl函數可以改變已經打開文件的性質。

        #i nclude

        #i nclude

        #i nclude

        int fcntl(int filedes, int cmd, ... ) ;

        返回:若成功則依賴于cmd(見下),若出錯為- 1。

        f c n t l函數有五種功能:

        n 復制一個現存的描述符, 新文件描述符作為函數值返(c m d=F_DUPFD)。

        n 獲得/設置文件描述符標記,對應于filedes 的文件描述符標志作為函數值返回.(c m d = F_GETFD或F_SETFD)。

        n 獲得/設置文件狀態標志,對應于filedes 的文件狀態標志作為函數值返回。(c m d = F_GETFL或F_SETFL)。

        n 獲得/設置異步I / O有權(c m d = F_GETOWN或F_SETOWN)。

        n 獲得/設置記錄鎖(c m d = F_SETLK , F_SETLKW)。

        關于加鎖和解鎖區域的說明還要注意下列各點:

        l 該區域可以在當前文件尾端處開始或越過其尾端處開始,但是不能在文件起始位置之前開始或越過該起始位置。

        l 如若l_len為0,則表示鎖的區域從其起點(由l_start和l_whence決定)開始直至最大可能位置為止。也就是不管添寫到該文件中多少數據,它都處于鎖的范圍。

        l 為了鎖整個文件,通常的方法是將l_start說明為0,l_whence說明為SEEK_SET,l_len說明為0。

        實例:

        /*fcntl_write.c測試文件寫入鎖主函數部分*/

        #i nclude unistd.h>

        #i nclude sys/file.h>

        #i nclude sys/types.h>

        #i nclude sys/stat.h>

        #i nclude stdio.h>

        #i nclude stdlib.h>

        /*lock_set函數*/

        void lock_set(int fd, int type)

        {

        struct flock lock;

        lock.l_whence = SEEK_SET;//賦值lock結構體

        lock.l_start = 0;

        lock.l_len =0;

        while(1)

        {

        lock.l_type = type;

        /*根據不同的type值給文件上鎖或解鎖*/

        if((fcntl(fd, F_SETLK, lock)) == 0)

        {

        if( lock.l_type == F_RDLCK )

        printf(read lock set by %dn,getpid());

        else if( lock.l_type == F_WRLCK )

        printf(write lock set by %dn,getpid());

        else if( lock.l_type == F_UNLCK )

        printf(release lock by %dn,getpid());

        return;

        }

        /*判斷文件是否可以上鎖*/

        fcntl(fd, F_GETLK,lock);

        /*判斷文件不能上鎖的原因*/

        if(lock.l_type != F_UNLCK)

        {

        /*/該文件已有寫入鎖*/

        if( lock.l_type == F_RDLCK )

        printf(read lock already set by %dn,lock.l_pid);

        /*該文件已有讀取鎖*/

        else if( lock.l_type == F_WRLCK )

        printf(write lock already set by %dn,lock.l_pid);

        getchar();

        }

        }

        }

        int main(void)

        {

        int fd;

        /*首先打開文件*/

        fd=open(hello,O_RDWR | O_CREAT, 0666);

        if(fd 0)

        {

        perror(open);

        exit(1);

        }

        /*給文件上寫入鎖*/

        lock_set(fd, F_WRLCK);

        getchar();

        /*給文件接鎖*/

        lock_set(fd, F_UNLCK);

        getchar();

        close(fd);

        exit(0);

        }

        開兩個終端分別運行,可看到先運行的那個終端,成功上鎖,后運行的那個無效。可見寫入鎖是互斥鎖,一個時候只能有一個寫入鎖存在

        select 實現I/O復用

        I/O處理的五種模型

        ① 阻塞I/O模型:若所調用的I/O函數沒有完成相關的功能就會使進程掛起,直到相關數據到達才會返回。如:終端、網絡設備的訪問。

        ② 非阻塞模型:當請求的I/O操作不能完成時,則不讓進程休眠,而且返回一個錯誤。如:open、read、write訪問。

        ③ I/O多路轉接模型:如果請求的I/O 操作阻塞,且他不是真正阻塞I/O,而且讓其中的一個函數等待,在這期間, I/O還能進行其他操作。如:select函數。

        ④ 信號驅動I/O模型:在這種模型下,通過安裝一個信號處理程序,系統可以自動捕獲特定信號的到來,從而啟動I/O。

        ⑤ 異步I/O模型:在這種模型下,當一個描述符已準備好,可以啟動I/O時,進程會通知內核。由內核進行后續處理,這種用法現在較少。

        select函數

        傳向select的參數告訴內核:

        (1) 我們所關心的描述符。

        (2) 對于每個描述符我們所關心的條件(是否讀一個給定的描述符?是否想寫一個給定的描述符?是否關心一個描述符的異常條件?)。

        (3) 希望等待多長時間(可以永遠等待,等待一個固定量時間,或完全不等待)。

        從s e l e c t返回時,內核告訴我們:

        (1) 已準備好的描述符的數量。

        (2) 哪一個描述符已準備好讀、寫或異常條件。

        #i nclude /* fd_set data type */

        #i nclude /* struct timeval */

        #i nclude /* function prototype might be here */

        int select (int numfds, fd_set *readfds,

        fd_set *writefds, fd_set *exceptfds, struct timeval * timeout) ;

        返回:準備就緒的描述符數,若超時則為0,若出錯則為- 1。

        timeout值:

        n NULL:永遠等待,直到捕捉到信號或文件描述符已準備好為止;

        n 具體值: struct timeval 類型的指針,若等待為timeout時間還沒有文件描述符準備好,就立即返回;

        n 0:從不等待,測試所有指定 的描述符并立即返回;

        先說明最后一個參數,它指定愿意等待的時間。



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 安仁县| 松阳县| 和平区| 富顺县| 东乡县| 蒲江县| 台东县| 吉林省| 乐平市| 泰和县| 大方县| 奉节县| 福贡县| 镇坪县| 南岸区| 印江| 岗巴县| 罗甸县| 泌阳县| 丰镇市| 辽中县| 通道| 清新县| 平湖市| 通辽市| 平乐县| 旬阳县| 洞头县| 麦盖提县| 灵宝市| 民丰县| 盘山县| 高州市| 中西区| 濉溪县| 石门县| 綦江县| 丰都县| 个旧市| 九龙县| 徐闻县|