守護程序之單例項守護程序

2021-09-06 13:47:30 字數 1719 閱讀 9334

為了正常執行,某些守護程序實現為單例項的,也就是在任一時刻只執行該守護程序的乙個副本。例如,該守護程序可能需要排它地訪問乙個裝置。在cron守護程序情況下,如果同時有多個例項執行,那麼每個副本都可能試圖開始某個預定的操作,於是造成該操作的重複執行,這很可能導致出錯。

如果守護程序需要訪問一裝置,而該裝置驅動程式將阻止多次開啟在/dev目錄下的相應裝置節點,那麼這就達到了任何時刻只執行守護程序乙個副本的要求。但是如果沒有這種裝置可供使用,那麼我們就需要自行處理。

檔案鎖和記錄鎖機制是一種方法的基礎,該方法用來保證乙個守護程序只有乙個副本在執行。如果每乙個守護程序建立乙個檔案,並且在整個檔案上加上一把寫鎖,那就只允許建立一把這樣的寫鎖,所以在此之後如試圖再建立一把這樣的寫鎖就將失敗,以此向後續守護程序副本指明已有乙個副本正在執行

檔案鎖和記錄鎖提供了一種方便的互斥機制。如果守護程序在整個檔案上得到一把寫鎖,那麼在該守護程序終止時,這把寫鎖將被自動刪除。這就簡化了復原所需的處理,去除了對以前的守護程序例項需要進行清理的有關操作。

例項

程式清單13-2中的函式說明了如何使用檔案和記錄鎖以保證只執行某守護程序的乙個副本。

程式清單13-2 保證只執行某個守護程序的乙個副本

#include #include 

#include

#include

#include

#include

#include

#include

#define lockfile "/var/run/daemon.pid"

#define lockmode (s_irusr|s_iwusr|s_irgrp|s_iroth)

extern

int lockfile(int

);int already_running(void

)

if(lockfile(fd) < 0

)

syslog(log_err,

"can't lock %s: %s

", lockfile, strerror(errno));

exit(1);

}ftruncate(fd, 0);

sprintf(buf,

"%ld

", (long

)getpid());

write(fd, buf, strlen(buf)+1

);

return(0

);}

守護程序的每個副本都將試圖建立乙個檔案,並將其程序id寫到該檔案中。這使管理人員易於標識該程序。如果該檔案已經加了鎖,那麼lockfile函式(見高階i/o之記錄鎖)將失敗,errno設定為eacces或eagain,函式返回1,這表明該守護程序已在執行。否則將檔案長度截短為0,將程序id寫入該檔案,函式返回0。

我們需要將檔案長度截短為0,其原因是以前守護程序例項的程序id字串可能長於呼叫此函式的當前程序的程序id字串。例如,若以前的守護程序的程序id是12345,而新例項的程序id是9999,那麼將此程序id寫入檔案後,在檔案中留下的是99995。將檔案長度截短為0就解決了此問題。

本篇博文內容摘自《unix環境高階程式設計》(第二版),僅作個人學習記錄所用。關於本書可參考:

守護程序之單例項

include include include include include include include include include include 建立守護程序函式 intdaemonize 重定向標準輸入 標準輸出和標準錯誤輸出 error open 0600 dup2 error,2...

守護程序之守護程序的慣例

在unix系統中,守護程序遵循下列公共慣例 例項 程式清單13 3所示程式說明了守護程序可以重讀其配置檔案的一種方法。該程式使用sigwait以及多執行緒 可參考 程式清單13 3 守護程序重讀配置檔案 include apue.h include include sigset t mask ext...

守護程序的單例項實現

守護程序的單例項實現 為了正常工作,守護程序應該實現為單例項的,也就是在任一時刻只執行該守護程序的乙個副本,因為這個守護程序要排它的訪問乙個裝置。這裡需要用到文 件鎖的機制,如果守護程序建立乙個檔案,並且在整個檔案上加上一把鎖,那就只允許建立一把這樣的寫鎖,在此之後如果試圖再建立一把這樣的寫鎖就將失...