日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

41-fcntl设置文件锁

發布時間:2024/3/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 41-fcntl设置文件锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 文件鎖

當多個進程打開同一文件進行讀寫時可能會出現數據混亂的問題,原因在于進程間共享同一文件讀寫指針位置,也就是f_pos(關于f_pos參考:4-文件描述符與打開的文件之間的關系的第三小節file結構體)。

解決這個問題的方法有很多,比如可以使用信號量完成進程同步,但通常使用文件鎖會更好一些,因為內核會將鎖跟文件關聯起來,這就需要借助fcntl函數來實現對一個文件進行加鎖。只有拿到鎖的進程可以對文件進行讀寫操作,而沒有獲得鎖的進程操作文件可以打開文件,但無法執行read、write操作,以此來防止進程間對同一文件進行讀寫出現的數據混亂問題。

?

2. fcntl函數

#include <unistd.h> #include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );

參數fd:指定文件描述符

?

參數cmd:一般用于設置文件鎖,F_SETLK和F_SETLKW 用于加鎖解鎖, F_GETLK用于獲取文件鎖。

F_SETLK設置文件鎖,如果另一進程已經加鎖,那么fcntl將會失敗并返回EAGAIN錯誤,不會阻塞。

F_SETLKW設置文件鎖,如果另一進程已經加鎖,那么該進程將會阻塞,直到文件鎖被釋放。

F_GETLK實際上是用于獲取文件鎖的相關信息,以檢測能否設置F_SETLK或F_SETLKW進行加鎖。

?

參數flock具體定義:

struct flock {...short l_type; //鎖的類型:F_RDLCK(讀方式加鎖) 、F_WRLCK(寫方式加鎖) 、F_UNLCK(解鎖)short l_whence; //參考偏移位置:SEEK_SET、SEEK_CUR、SEEK_END off_t l_start; //具體起始偏移位置,0表示文件開頭off_t l_len; //長度:其實是表示加鎖的范圍(加多少個字節),如果為0表示整個文件加鎖pid_t l_pid; //持有該鎖的進程ID:(只有調用F_GETLK only,才會用到這個參數)... };

?

加鎖范圍:

1. 如果 len > 0, [whence+start??,??whence+start+len)?,包左不包右

2. 如果 len = 0, [whence+start??,?∞),包左不包右,表示對整個文件加鎖

以whence為參考位置開始,加上start就是具體的起始位置。例如:whence = SEEK_SET,start = 10,那么參考位置就是文件開頭(偏移為0的位置),加上start后,具體的起始位置就是偏移為10的位置。

?

3. 文件鎖示例

多個進程對加鎖文件進行訪問:

1. 首先測試兩個進程間以讀方式加鎖

2. 然后測試兩個進程間以寫方式加鎖

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h>void sys_err(char *str){perror(str);exit(1); }int main(int argc, char *argv[]) {int fd;struct flock f_lock;//參數不夠if (argc < 2) {printf("./a.out filename\n");exit(1);}//打開文件失敗if ((fd = open(argv[1] , O_RDWR)) < 0){sys_err("open");}//選用寫瑣f_lock.l_type = F_WRLCK; //選用讀瑣 //f_lock.l_type = F_RDLCK; //設置文件指針為文件開頭f_lock.l_whence = SEEK_SET;//起始偏移,0表示文件開頭f_lock.l_start = 0;// l_len表示加鎖的長度,0表示整個文件加鎖 f_lock.l_len = 0; //設置屬性,讓線程阻塞(F_SETLKW),直到加鎖成功fcntl(fd, F_SETLKW, &f_lock);//如果加鎖成功,打印get flockprintf("get flock\n");//為了測試效果明顯,休眠10秒sleep(10);//設置鎖類型為解鎖f_lock.l_type = F_UNLCK;//設置屬性,解鎖不成功阻塞fcntl(fd, F_SETLKW, &f_lock);//解鎖成功打印unflockprintf("un flock\n");close(fd);return 0; }

?

測試兩個進程間以寫方式加鎖,程序執行結果:

從圖中可以看出,以寫方式進行加鎖的話,那么左1進程對文件以寫方式加鎖成功,右1進程對文件以寫方式加鎖會失敗并阻塞,等到左1進程釋放寫鎖后,右1進程立馬獲取到了寫鎖。

?

?

修改部分代碼,測試兩個進程間以讀方式加鎖:

//選用寫瑣 //f_lock.l_type = F_WRLCK; //選用讀瑣 f_lock.l_type = F_RDLCK;

以讀方式進行加鎖的話,那么左1進程對文件以讀方式加鎖成功,右1進程對文件以讀方式加鎖也會成功。

由此我們可以得出結論:進程間對文件進行加文件鎖也遵循“讀共享、寫獨占”特性。但!如若進程不加鎖直接操作文件,依然可訪問成功,但數據勢必會出現混亂。

?

?

總結

以上是生活随笔為你收集整理的41-fcntl设置文件锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。