(1) pid 檔案的內容:pid 檔案為文字檔案,內容只有一行, 記錄了該程式的 ID 。
用 cat 命令可以看到。
(2) pid 檔案的作用:防止程式啟動多個副本。只有獲得 pid 檔案 (固定路徑固定檔名) 寫入許可權 (F_WRLCK) 的程式才能正常啟動並把自身的 PID 寫入該檔案中。其它同一個程式的多餘程式則自動退出。
(3) 程式設計技巧:
呼叫 fcntl 設定 pid 檔案的鎖定 F_SETLK 狀態,其中鎖定的標誌位 F_WRLCK 。
如果成功鎖定,則寫入程式當前 PID,程式繼續往下執行。
如果鎖定不成功,說明已經有同樣的程式在執行了,當前程式結束退出。
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
if (fcntl(fd, F_SETLK, &lock) < 0){ //鎖定不成功, 退出…… } sprintf (buf, “%dn”, (int) pid); pidsize = strlen(buf); if ((tmp = write (fd, buf, pidsize)) != (int)pidsize){ //寫入不成功, 退出…… } (4) 一些注意事項: i) 如果程式退出,則該程式加的鎖自動失效。 ii) 如果程式關閉了該檔案描述符 fd, 則加的鎖失效。 (整個程式執行期間不能關閉此檔案描述符) iii) 鎖的狀態不會被子程式繼承。如果程式關閉則鎖失效而不管子程式是否在執行。 (Locks are associated with processes. A process can only have one kind of lock set for each byte of a given file. When any file descriptor for that file is closed by the process, all of the locks that process holds on that file are released, even if the locks were made using other descriptors that remain open. Likewise, locks are released when a process exits, and are not inherited by child processes created using fork.) (5) 參考資料: fcntl(檔案鎖) 表標頭檔案 #include #include 函式定義 int fcntl(int fd, int cmd, struct flock *lock); 函式解釋 fd: 檔案描寫符 設定的檔案描寫符,引數 cmd 代表欲壟斷的號召 F_DUPFD 複製引數 fd 的檔案描寫符,厲行獲勝則歸來新複製的檔案描寫符, F_GETFD 獲得 close-on-exec 符號,若些符號的 FD_CLOEXEC 位為 0,代表在呼叫 exec() 相干函式時檔案將不會關閉 F_SETFD 設定 close-on-exec 符號,該符號以引數 arg 的 FD_CLOEXEC 位定奪 F_GETFL 獲得 open() 設定的符號 F_SETFL 改換 open() 設定的符號 F_GETLK 獲得檔案鎖定的事態,依據 lock 的描寫,定奪是否上檔案鎖 F_SETLK 設定檔案鎖定的事態,此刻 flcok,構造的 l_tpye 值定然是 F_RDLCK 、 F_WRLCK 或 F_UNLCK, 萬一無法發生鎖定,則歸來-1 F_SETLKW 是 F_SETLK 的阻塞版本,在無法獲得鎖時會進去睡眠事態,萬一能夠獲得鎖可能捉拿到訊號則歸來 引數 lock 指標為 flock 構造指標定義如下 struct flock { … short l_typejngaoy.com; short l_whence; off_t l_start; 鎖定區域的開關位置 off_t l_len; 鎖定區域的大小 pid_t l_pid; 鎖定動作的歷程 … }; 1_type 有三種事態: F_RDLCK 讀取鎖(分享鎖) F_WRLCK 寫入鎖(排斥鎖) F_UNLCK 解鎖 l_whence 也有三種措施 SEEK_SET 以檔案開始為鎖定的起始位置 SEEK_CUR 以現在檔案讀寫位置為鎖定的起始位置 SEEK_END 以檔案尾為鎖定的起始位置 歸來值 獲勝則歸來 0,若有訛謬則歸來-1 l_len: 加鎖區的長度 l_pid: 具有阻塞目前歷程的鎖,其持有歷程的歷程號儲藏在 l_pid 中,由 F_GETLK 歸來 等閒是將 l_start 設定為 0,l_whence 設定為 SEEK_SET,l_len 設定為 0