Linux 系統程式設計的技巧:使用 fcntl() 實作讀寫鎖
讀寫鎖是一種常用的同步機制,它可以讓多個行程或執行緒對同一個資源進行並發的讀取操作,或是互斥的寫入操作,從而提高系統的效率和安全性。在 Linux 系統程式設計中,有多種方法可以實作讀寫鎖,例如使用 pthread 函式庫、使用檔案鎖等。本文將為你介紹一種使用 fcntl() 系統呼叫實作讀寫鎖的方法,以及它的原理、用法和優缺點,讓你在 Linux 系統程式設計中更好地使用和理解這個技巧。
#在多進程對同一個檔案進行讀寫存取時,為了確保資料的完整性,有事需要對檔案進行鎖定。可以透過fcntl()函數對檔案進行鎖定和解鎖。
\1. fcntl
1.1.功能描述:根據文件描述詞來操作文件的特性。
1.2.用法:
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
fd:檔案描述詞。
cmd:操作指令。
arg:供指令使用的參數,是否需要arg參數跟cmd指令有關。
lock:鎖定資訊。
2.讀寫鎖定實例
新建兩個文件,原始碼如下2.1、2.2所示。
2.1.為檔案加讀鎖定
#include \#include \#include \#include \#include int main(int argc, const char * argv [ ]) { int fd = open("test.c", O_RDONLY); if (fd == -1) { perror("open failed:"); return -1; } struct stat sta; fstat(fd,&sta); struct flock lock; lock.l_len = sta.st_size; lock.l_pid = getpid(); lock.l_start = 0; lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; printf("进程pid: %d\n",lock.l_pid); if(fcntl(fd,F_SETLK,&lock) == -1) { perror("fcntl fail "); return -1; } else { printf("add read lock success!\n"); } sleep(10); close(fd); return 0; } 2.2.给文件加写锁 \#include \#include \#include \#include \#include int main(int argc, const char * argv [ ]) { int fd = open("test.c", O_WRONLY); if (fd == -1) { perror("open failed:"); return -1; } struct stat sta; fstat(fd,&sta); struct flock lock; lock.l_len = sta.st_size; lock.l_pid = getpid(); lock.l_start = 0; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; printf("进程pid: %d\n",lock.l_pid); while(fcntl(fd,F_SETLK,&lock) == -1 ) { perror("fcntl:"); sleep(1); struct flock lock_1; lock_1 = lock; lock_1.l_type = F_WRLCK; // fcntl(fd,F_GETLK,&lock_1);//获取文件锁状态,及加锁(lock_1.l_type)能否成功 switch(lock_1.l_type) { case F_RDLCK: printf("检测到读锁 pid = %d \n",lock_1.l_pid); break; case F_WRLCK: printf("检测到写锁 pid = %d \n",lock_1.l_pid); break; case F_UNLCK: printf("检测到已解锁.pid = %d \n",lock_1.l_pid); } } printf("写锁设置成功\n"); getchar(); close(fd); return 0; }
/*
注意:
1、fcntl(fd,F_GETLK,&lock_1)中的lock_1必須初始化,且lock_1.l_type必須設定為對應的鎖,才能確定能否加鎖成功,及不成功的原因。
2、GETLK時,fcntl先偵測有沒有能阻止本次加鎖的鎖,如果有,則覆寫flock結構體(lock_1)的資訊。如果沒有,則置lock_1.l_type 的類型為F_UNLCK。
*/
對於寫鎖(F_WRLCK 獨佔鎖),只有一個程序可以在檔案的任一特定區域上享有獨佔鎖。
對於讀鎖(F_RDLCK 共用鎖定),許多不同的程序可以同時擁有檔案上同一區域上的共用鎖定。為了擁有共享鎖,文件必須以讀取或讀取/寫入的方式開啟。只要任一進程擁有共享鎖,那麼其他進程就無法再獲得獨佔鎖。
分別編譯執行:
3.先執行讀鎖,再執行寫入鎖定。結果如下:
#liu@ubuntu:~/learn/lrn_linux$ ./readlock.out 进程pid: 16458 add read lock success! liu@ubuntu:~/learn/lrn_linux$ ./writelock.out 进程pid: 16459 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到已解锁.pid = 16459
寫入鎖定設定成功
可以看出,當檔案被讀鎖定佔用時,無法新增寫入鎖定(獨佔鎖定)
4.先運行寫鎖,再運行讀鎖的話,結果如下:
liu@ubuntu:~/learn/lrn_linux$ ./writelock.out
進程pid: 16349
寫入鎖定設定成功
liu@ubuntu:~/learn/lrn_linux$ ./readlock.out
進程pid: 16350
fcntl fail : Resource temporarily unavailable
所以,加鎖是成功的。
透過本文,你應該對 Linux 系統程式設計中使用 fcntl() 實作讀寫鎖的方法有了一個基本的了解,知道了它的原理、用法和優缺點。你也應該明白了使用 fcntl() 實作讀寫鎖的目的和影響,以及如何在 Linux 系統程式設計中正確地使用和配置 fcntl()。我們建議你在需要實現讀寫鎖的場景中,使用 fcntl() 來實現你的目標。同時,我們也提醒你在使用 fcntl() 時要注意一些潛在的問題和挑戰,如相容性、可移植性、效能等。希望這篇文章能幫助你更好地使用 Linux 系統編程,讓你在 Linux 下掌握 fcntl() 的技巧和優勢。
以上是Linux 系統程式設計的技巧:使用 fcntl() 實作讀寫鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

在 Sublime 中運行代碼的方法有六種:通過熱鍵、菜單、構建系統、命令行、設置默認構建系統和自定義構建命令,並可通過右鍵單擊項目/文件運行單個文件/項目,構建系統可用性取決於 Sublime Text 的安裝情況。

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

要安裝 Laravel,需依序進行以下步驟:安裝 Composer(適用於 macOS/Linux 和 Windows)安裝 Laravel 安裝器創建新項目啟動服務訪問應用程序(網址:http://127.0.0.1:8000)設置數據庫連接(如果需要)

Visual Studio Code (VSCode) 是一款跨平台、開源且免費的代碼編輯器,由微軟開發。它以輕量、可擴展性和對眾多編程語言的支持而著稱。要安裝 VSCode,請訪問官方網站下載並運行安裝程序。使用 VSCode 時,可以創建新項目、編輯代碼、調試代碼、導航項目、擴展 VSCode 和管理設置。 VSCode 適用於 Windows、macOS 和 Linux,支持多種編程語言,並通過 Marketplace 提供各種擴展。它的優勢包括輕量、可擴展性、廣泛的語言支持、豐富的功能和版
