如何讓服務只執行單個例項
2011-01-20 15:37:40
分類: c/c++
對於很多服務來說,在同乙個伺服器上只能執行乙個例項,那麼通過什麼方法來保證程式同一時刻只有乙個例項執行呢?通過編寫shell指令碼來管理程式的啟動、停止是個不錯的方法。在啟動時,shell指令碼會建立程序標識檔案(儲存正在執行例項的pid)以表明已經有例項在執行,如果檔案已存在,則說明已有例項在執行,不需要做任何事;在退出時,shell指令碼會刪除程序標識檔案,表明沒有例項執行。
shell指令碼管理方法在應用程式之上再包了一層,那麼能不能直接在程式開始執行時自己判斷是否有例項在執行呢,答案是肯定的。原理其實差不多,還是要借助公用資源---檔案,當然不僅僅是檔案而已,還需要檔案鎖的支援。大致思路是這樣的:程式在開始執行時對特定檔案進行加鎖(不存在則建立),如果加鎖成功,則例項開始執行;如鎖已經被占有,則說明已經有例項在執行,則程式直接退出;另外在例項執行完畢後對檔案的鎖也隨著丟掉了。這樣就能保證每次只有乙個程式例項在執行。
具體步驟如下:
1.開啟特定檔案(如/var/run/mydaemon.pid),如不存在則建立之;
2.使用fcntl對檔案整個區域加勸告鎖。
3.如果加鎖成功,則繼續執行後續**,並將pid寫入檔案;如加鎖不成功,說明已經有例項在執行,直接退出。
實現示例:
#include
#include
#include
#include
#include
#include
#include
#include
#define lockfile "/var/run/mydaemon.pid"
#define lockmode (s_irusr | s_iwusr | s_irgrp | s_iroth)
/* set advisory lock on file */
int lockfile(int fd)
struct flock fl;
fl.l_type = f_wrlck; /* write lock */
fl.l_start = 0;
fl.l_whence = seek_set;
fl.l_len = 0; //lock the whole file
return(fcntl(fd, f_setlk, &fl));
int already_running(const char *filename)
int fd;
char buf[16];
fd = open(filename, o_rdwr | o_creat, lockmode);
if (fd < 0) {
printf("can't open %s: %m\n", filename);
exit(1);
/* 先獲取檔案鎖 */
if (lockfile(fd) == -1) {
if (errno == eacces || errno == eagain) {
printf("file: %s already locked", filename);
close(fd);
return 1;
printf("can't lock %s: %m\n", filename);
exit(1);
/* 寫入執行例項的pid */
ftruncate(fd, 0);
sprintf(buf, "%ld", (long)getpid());
write(fd, buf, strlen(buf) + 1);
return 0;
int main(int argc, char *argv)
if (already_running(lockfile))
return 0;
/* 在這裡新增工作** */
printf("start main...\n");
sleep(100);
printf("main done!\n");
exit(0);
讓MFC程式只執行單個例項 的簡單示例
這裡只是簡單的建立乙個mfc 程式來演示 只執行乙個例項。在標頭檔案中新增類似如下 define scansettings classname t scansettingswindowclass 在原始檔中新增如下 if pwndprev null bring the main window or ...
如何讓程式只執行一次例項
最近在做乙個系統的客戶端時,遇到乙個問題 客戶端執行在伺服器上時,如果同乙個使用者或其他使用者執行了這個客戶端,可能會導致錯誤。這就要求該程式的例項只能執行一次。using system using system.collections.generic using system.windows.fo...
如何讓程式只執行一次例項
using system using system.runtime.interopservices using system.windows.forms using system.diagnostics using system.reflection loop through the running...