程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> fcntl函數的應用詳解

fcntl函數的應用詳解

編輯:關於C++

fcntl函數的應用詳解。本站提示廣大學習愛好者:(fcntl函數的應用詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是fcntl函數的應用詳解正文


(1)fcntl函數解釋 後面的這5個根本函數完成了文件的翻開、讀寫等根本操作,這一節將評論辯論的是,在文 件曾經同享的情形下若何操作,也就是當多個用戶配合應用、操作一個文件的情形,這時候,Linux 平日采取的辦法是給文件上鎖,來防止同享的資本發生競爭的狀況。 文件鎖包含建議性鎖和強迫性鎖。 建議性鎖請求每一個上鎖文件的過程都要檢討能否有鎖存,而且尊敬已有的鎖。在普通情形下,內核和體系都不應用建議性鎖。強迫性鎖是由內 核履行的鎖,當一個文件被上鎖停止寫入操作的時刻,內核將阻攔其他任何文件對其停止讀寫操作。采取強迫性鎖對機能的影響很年夜,每次讀寫操作都必需檢討能否有鎖存在。 在 Linux 中,完成文件上鎖的函數有lock和fcntl,個中flock用於對文件施加建議性鎖,而fcntl不只可以施加建議性鎖,還可以施增強制鎖。同時,fcntl還能對文件的某一記載停止上鎖,也就是記載鎖。 記載鎖又可分為讀取鎖和寫入鎖,個中讀取鎖又稱為同享鎖,它可以或許使多個過程都能在文件的統一部門樹立讀取鎖。而寫入鎖又稱為排擠鎖,在任什麼時候刻只能有一個過程在文件的某個部門上樹立寫入鎖。固然,在文件的統一部門不克不及同時樹立讀取鎖和寫入鎖。 留意: fcntl是一個異常通用的函數,它還可以轉變文件過程各方面的屬性,在本節中,重要引見它樹立記載鎖的辦法,關於它其他用戶感興致的讀者可以參看fcntl手冊。 (2)fcntl函數格局 用於樹立記載鎖的fcntl函數格局如表6.6 所示。 表6.6 fcntl函數語法要點所需頭文件

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

函數原型int fcnt1(int fd, int cmd, struct flock *lock) fd:文件描寫符 F_DUPFD:復制文件描寫符 F_GETFD:取得fd的close-on-exec標記,若標記未設置,則文件經由exec函數以後仍堅持翻開狀況 F_SETFD:設置close-on-exec標記,該標記以參數arg的FD_CLOEXEC位決議 F_GETFL:獲得open設置的標記 函數傳入值 cmd F_SETFL:轉變open設置的標記 F_GETFK:依據lock描寫,決議能否上文件鎖 F_SETFK:設置lock描寫的文件鎖 F_SETLKW:這是F_SETLK的壅塞版本(敕令名中的W表現期待(wait))。 假如存在其他鎖,則挪用過程睡眠;假如捕獲到旌旗燈號則睡眠中止 F_GETOWN:檢索將收到SIGIO和SIGURG旌旗燈號的過程號或過程組號 F_SETOWN:設置過程號或過程組號 函數前往值 Lock:構造為flock,設置記載鎖的詳細狀況,前面會具體解釋 勝利:0 -1:失足 這裡,lock的構造以下所示:

Struct flock{
short l_type;
off_t l_start;
short l_whence;
off_t l_len;
pid_t l_pid;
}
lock構造中每一個變量的取值寄義如表6.7 所示。 表6.7 lock構造變量取值
F_RDLCK:讀取鎖(同享鎖) l_type F_WRLCK:寫入鎖(排擠鎖) F_UNLCK:解鎖 l_stat 絕對位移量(字節) SEEK_SET:以後地位為文件的開首,新地位為偏移量的年夜小 SEEK_CUR:以後地位為文件指針的地位,新地位為以後地位加上偏移量 l_whence:絕對位移量的終點(同lseek 的whence)。 SEEK_END:以後地位為文件的開頭,新地位為文件的年夜小加上偏移量的年夜小 l_len 加鎖區域的長度
小技能: 為加鎖全部文件,平日的辦法是將l_start 解釋為0,l_whence 解釋為SEEK_SET,l_len 解釋為0。 (3)fcntl應用實例 上面起首給出了應用fcntl 函數的文件記載鎖函數。在該函數中,起首給flock 構造體的對應位付與響應的值。接著應用兩次fcntl函數分離用於給相干文件上鎖和斷定文件能否可以上鎖,這裡用到的cmd值分離為F_SETLK 和F_GETLK。 這個函數的源代碼以下所示:
/*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 %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();
}
}
}

上面的實例是測試文件的寫入鎖,這裡起首創立了一個hello文件,以後對其上寫入鎖,最初釋放寫入鎖。代碼以下所示:

/*fcntl_write.c測試文件寫入鎖主函數部門*/
#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);
}

為了可以或許應用多個終端,更好地顯示寫入鎖的感化,本實例重要在PC 機上測試,讀者可將其穿插編譯,下載到目的板上運轉。上面是在PC 機上的運轉成果。為了使法式有較年夜的靈巧性,筆者采取文件上鎖後由用戶鍵入一隨意率性鍵使法式持續運轉。建議讀者開啟兩個終端,而且在兩個終端上同時運轉該法式,以到達多個過程操作一個文件的後果。在這裡,筆者起首運轉終端一,請讀者留意終端二中的第一句。
終端一:

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

終端二:

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

因而可知,寫入鎖為互斥鎖,一個時辰只能有一個寫入鎖存在。
接上去的法式是測試文件的讀取鎖,道理同下面的法式一樣。

/*fcntl_read.c測試文件讀取鎖主函數部門*/
#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);
}

異樣開啟兩個終端,並起首啟動終端一上的法式,其運轉成果以下所示:
終端一:

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

終端二:

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

讀者可以將此成果與寫入鎖的運轉成果比擬較,可以看出,讀取鎖為同享鎖,當過程5009已設定讀取鎖後,過程5010 還可以設置讀取鎖。
思慮:
假如在一個終端上運轉設置讀取鎖,則在另外一個終端上運轉設置寫入鎖,會有甚麼成果呢?
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved