最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

fcntl函數(shù)的使用詳解

 更新時間:2013年05月31日 16:24:14   作者:  
本篇文章是對fcntl函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
(1)fcntl函數(shù)說明
前面的這5個基本函數(shù)實(shí)現(xiàn)了文件的打開、讀寫等基本操作,這一節(jié)將討論的是,在文 件已經(jīng)共享的情況下如何操作,也就是當(dāng)多個用戶共同使用、操作一個文件的情況,這時,Linux 通常采用的方法是給文件上鎖,來避免共享的資源產(chǎn)生競爭的狀態(tài)。
文件鎖包括建議性鎖強(qiáng)制性鎖
建議性鎖要求每個上鎖文件的進(jìn)程都要檢查是否有鎖存,并且尊重已有的鎖。在一般情況下,內(nèi)核和系統(tǒng)都不使用建議性鎖。強(qiáng)制性鎖是由內(nèi) 核執(zhí)行的鎖,當(dāng)一個文件被上鎖進(jìn)行寫入操作的時候,內(nèi)核將阻止其他任何文件對其進(jìn)行讀寫操作。采用強(qiáng)制性鎖對性能的影響很大,每次讀寫操作都必須檢查是否有鎖存在。
在 Linux 中,實(shí)現(xiàn)文件上鎖的函數(shù)有l(wèi)ock和fcntl,其中flock用于對文件施加建議性鎖,而fcntl不僅可以施加建議性鎖,還可以施加強(qiáng)制鎖。同時,fcntl還能對文件的某一記錄進(jìn)行上鎖,也就是記錄鎖。
記錄鎖又可分為讀取鎖寫入鎖,其中讀取鎖又稱為共享鎖,它能夠使多個進(jìn)程都能在文件的同一部分建立讀取鎖。而寫入鎖又稱為排斥鎖,在任何時刻只能有一個進(jìn)程在文件的某個部分上建立寫入鎖。當(dāng)然,在文件的同一部分不能同時建立讀取鎖和寫入鎖。
注意:
fcntl是一個非常通用的函數(shù),它還可以改變文件進(jìn)程各方面的屬性,在本節(jié)中,主要介紹它建立記錄鎖的方法,關(guān)于它其他用戶感興趣的讀者可以參看fcntl手冊。
(2)fcntl函數(shù)格式
用于建立記錄鎖的fcntl函數(shù)格式如表6.6 所示。
表6.6 fcntl函數(shù)語法要點(diǎn)所需頭文件
復(fù)制代碼 代碼如下:

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

函數(shù)原型int fcnt1(int fd, int cmd, struct flock *lock)
fd:文件描述符
F_DUPFD:復(fù)制文件描述符
F_GETFD:獲得fd的close-on-exec標(biāo)志,若標(biāo)志未設(shè)置,則文件經(jīng)過exec函數(shù)之后仍保持打開狀態(tài)
F_SETFD:設(shè)置close-on-exec標(biāo)志,該標(biāo)志以參數(shù)arg的FD_CLOEXEC位決定
F_GETFL:得到open設(shè)置的標(biāo)志
函數(shù)傳入值
cmd
F_SETFL:改變open設(shè)置的標(biāo)志
F_GETFK:根據(jù)lock描述,決定是否上文件鎖
F_SETFK:設(shè)置lock描述的文件鎖
F_SETLKW:這是F_SETLK的阻塞版本(命令名中的W表示等待(wait))。
如果存在其他鎖,則調(diào)用進(jìn)程睡眠;如果捕捉到信號則睡眠中斷
F_GETOWN:檢索將收到SIGIO和SIGURG信號的進(jìn)程號或進(jìn)程組號
F_SETOWN:設(shè)置進(jìn)程號或進(jìn)程組號
函數(shù)返回值
Lock:結(jié)構(gòu)為flock,設(shè)置記錄鎖的具體狀態(tài),后面會詳細(xì)說明
成功:0
-1:出錯
這里,lock的結(jié)構(gòu)如下所示:
復(fù)制代碼 代碼如下:

Struct flock{
short l_type;
off_t l_start;
short l_whence;
off_t l_len;
pid_t l_pid;
}
lock結(jié)構(gòu)中每個變量的取值含義如表6.7 所示。
表6.7 lock結(jié)構(gòu)變量取值
F_RDLCK:讀取鎖(共享鎖)
l_type F_WRLCK:寫入鎖(排斥鎖)
F_UNLCK:解鎖
l_stat 相對位移量(字節(jié))
SEEK_SET:當(dāng)前位置為文件的開頭,新位置為偏移量的大小
SEEK_CUR:當(dāng)前位置為文件指針的位置,新位置為當(dāng)前位置加上偏移量
l_whence:相對位移量的起點(diǎn)(同lseek 的whence)。
SEEK_END:當(dāng)前位置為文件的結(jié)尾,新位置為文件的大小加上偏移量的大小
l_len 加鎖區(qū)域的長度
小技巧:
為加鎖整個文件,通常的方法是將l_start 說明為0,l_whence 說明為SEEK_SET,l_len 說明為0。
(3)fcntl使用實(shí)例
下面首先給出了使用fcntl 函數(shù)的文件記錄鎖函數(shù)。在該函數(shù)中,首先給flock 結(jié)構(gòu)體的對應(yīng)位賦予相應(yīng)的值。接著使用兩次fcntl函數(shù)分別用于給相關(guān)文件上鎖和判斷文件是否可以上鎖,這里用到的cmd值分別為F_SETLK 和F_GETLK。
這個函數(shù)的源代碼如下所示:
復(fù)制代碼 代碼如下:

/*lock_set函數(shù)*/
void lock_set(int fd, int type)
{
struct flock lock;
lock.l_whence = SEEK_SET;//賦值lock結(jié)構(gòu)體
lock.l_start = 0;
lock.l_len =0;
while(1){
lock.l_type = type;
/*根據(jù)不同的type值給文件上鎖或解鎖*/
if((fcntl(fd, F_SETLK, &lock)) == 0){
if( lock.l_type == F_RDLCK )
printf("read lock set by %d\n",getpid());
else if( lock.l_type == F_WRLCK )
printf("write lock set by %d\n",getpid());
else if( lock.l_type == F_UNLCK )
printf("release lock by %d\n",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 %d\n",lock.l_pid);
/*該文件已有讀取鎖*/
else if( lock.l_type == F_WRLCK )
printf("write lock already set by %d\n",lock.l_pid);
getchar();
}
}
}

下面的實(shí)例是測試文件的寫入鎖,這里首先創(chuàng)建了一個hello文件,之后對其上寫入鎖,最后釋放寫入鎖。代碼如下所示:
復(fù)制代碼 代碼如下:

/*fcntl_write.c測試文件寫入鎖主函數(shù)部分*/
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
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);
}

為了能夠使用多個終端,更好地顯示寫入鎖的作用,本實(shí)例主要在PC 機(jī)上測試,讀者可將其交叉編譯,下載到目標(biāo)板上運(yùn)行。下面是在PC 機(jī)上的運(yùn)行結(jié)果。為了使程序有較大的靈活性,筆者采用文件上鎖后由用戶鍵入一任意鍵使程序繼續(xù)運(yùn)行。建議讀者開啟兩個終端,并且在兩個終端上同時運(yùn)行該程序,以達(dá)到多個進(jìn)程操作一個文件的效果。在這里,筆者首先運(yùn)行終端一,請讀者注意終端二中的第一句。
終端一:
復(fù)制代碼 代碼如下:

[root@localhost file]# ./fcntl_write
write lock set by 4994
release lock by 4994

終端二:
復(fù)制代碼 代碼如下:

[root@localhost file]# ./fcntl_write
write lock already set by 4994
write lock set by 4997
release lock by 4997

由此可見,寫入鎖為互斥鎖,一個時刻只能有一個寫入鎖存在。
接下來的程序是測試文件的讀取鎖,原理同上面的程序一樣。
復(fù)制代碼 代碼如下:

/*fcntl_read.c測試文件讀取鎖主函數(shù)部分*/
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int fd;
fd=open("hello",O_RDWR | O_CREAT, 0666);
if(fd < 0){
perror("open");
exit(1);
}
/*給文件上讀取鎖*/
lock_set(fd, F_RDLCK);
getchar();
/*給文件接鎖*/
lock_set(fd, F_UNLCK);
getchar();
close(fd);
exit(0);
}

同樣開啟兩個終端,并首先啟動終端一上的程序,其運(yùn)行結(jié)果如下所示:
終端一:
復(fù)制代碼 代碼如下:

[root@localhost file]# ./fcntl2
read lock set by 5009
release lock by 5009

終端二:
復(fù)制代碼 代碼如下:

[root@localhost file]# ./fcntl2
read lock set by 5010
release lock by 5010

讀者可以將此結(jié)果與寫入鎖的運(yùn)行結(jié)果相比較,可以看出,讀取鎖為共享鎖,當(dāng)進(jìn)程5009已設(shè)定讀取鎖后,進(jìn)程5010 還可以設(shè)置讀取鎖。
思考:
如果在一個終端上運(yùn)行設(shè)置讀取鎖,則在另一個終端上運(yùn)行設(shè)置寫入鎖,會有什么結(jié)果呢?

相關(guān)文章

  • C++中的boost::function庫簡介

    C++中的boost::function庫簡介

    這篇文章介紹了C++中的boost::function庫,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 解讀構(gòu)造函數(shù)的調(diào)用規(guī)則、深拷貝與淺拷貝

    解讀構(gòu)造函數(shù)的調(diào)用規(guī)則、深拷貝與淺拷貝

    本文主要介紹了C++中的默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)以及深拷貝和淺拷貝的概念,并通過實(shí)際代碼示例進(jìn)行了詳細(xì)講解
    2024-11-11
  • C語言實(shí)現(xiàn)對bmp格式圖片打碼

    C語言實(shí)現(xiàn)對bmp格式圖片打碼

    這篇文章主要介紹了C語言實(shí)現(xiàn)對bmp格式圖片打碼
    2016-01-01
  • 數(shù)據(jù)結(jié)構(gòu) 紅黑樹的詳解

    數(shù)據(jù)結(jié)構(gòu) 紅黑樹的詳解

    這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu) 紅黑樹的詳解的相關(guān)資料,數(shù)據(jù)結(jié)構(gòu)中的二叉樹查找,紅黑樹的講解,需要的朋友可以參考下
    2017-07-07
  • C++模擬實(shí)現(xiàn)List迭代器詳解

    C++模擬實(shí)現(xiàn)List迭代器詳解

    list不同于其他容器,他是一個鏈表,物理地址并不連續(xù)。所以在實(shí)現(xiàn)list類的迭代器的時候,需要將迭代器單獨(dú)封裝到一個類里,因?yàn)樾枰剌d很多操作符來跟其他容器的迭代器使用達(dá)成一致
    2022-04-04
  • 淺談C++內(nèi)存管理基礎(chǔ)知識

    淺談C++內(nèi)存管理基礎(chǔ)知識

    這篇文章主要為大家介紹了C++的內(nèi)存管理,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • Jsoncpp的安裝與使用方式

    Jsoncpp的安裝與使用方式

    JsonCpp是一個用于解析和生成JSON數(shù)據(jù)的C++庫,它支持解析JSON文件或字符串到C++對象,以及將C++對象序列化回JSON格式,安裝JsonCpp可以通過命令安裝,默認(rèn)安裝動態(tài)庫,JsonCpp的使用主要涉及三個類:Json::Value用于表示JSON值
    2025-01-01
  • 查找算法之二分查找的C++實(shí)現(xiàn)

    查找算法之二分查找的C++實(shí)現(xiàn)

    今天小編就為大家分享一篇關(guān)于查找算法之二分查找的C++實(shí)現(xiàn),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C語言 main 函數(shù)詳情

    C語言 main 函數(shù)詳情

    這篇文章主要介紹C語言 main 函數(shù),文章將圍繞C語言 main 函數(shù)相關(guān)資料詳細(xì)展開,需要的朋友可以參考一下
    2021-10-10
  • CStdioFile的用法詳細(xì)解析

    CStdioFile的用法詳細(xì)解析

    CStdioFile 不支持Duplicate,LockRange,和UnlockRange 這幾個CFile 函數(shù)。如果在CStdioFile 中調(diào)用了這幾個函數(shù),將會出現(xiàn)CNoSupported 異常
    2013-09-09

最新評論

皋兰县| 黄龙县| 湖南省| 无为县| 当雄县| 报价| 东丰县| 图木舒克市| 黄梅县| 萝北县| 江津市| 洱源县| 曲阜市| 如皋市| 田林县| 邯郸市| 马边| 丹棱县| 拉孜县| 方山县| 阜平县| 曲阳县| 宜川县| 富顺县| 京山县| 陵川县| 禄丰县| 天水市| 龙门县| 古丈县| 繁昌县| 白水县| 大竹县| 富裕县| 丹巴县| 勃利县| 海南省| 古丈县| 靖远县| 鄂尔多斯市| 分宜县|