如何讓服務只執行單個例項

2021-06-20 18:38:05 字數 2028 閱讀 1275

如何讓服務只執行單個例項

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...