程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Linux守護進程實現程序只運行一次,linux守護進程

Linux守護進程實現程序只運行一次,linux守護進程

編輯:關於C語言

Linux守護進程實現程序只運行一次,linux守護進程


1.守護進程

守護進程(Daemon)是一種運行在後台的特殊進程,它獨立於控制終端並且周期性的執行某種任務或等待處理某些發生的事件。

2.讓程序只運行一次

如果讓程序只運行一次,有很多方法,此處的一種方法是創建一個名字古怪的文件(保證不跟系統文件或其他文件重名),判斷文件存在則讓程序不再運行且提示程序正在運行,如果不存在則可以運行。

3.測試代碼

此代碼額外添加了系統LOG,記錄操作的信息。

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <syslog.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <fcntl.h>
  8 #include <errno.h>
  9 
 10 #define FILE    "/var/cxl_single_file"
 11 
 12 // 函數聲明
 13 void create_daemon(void);
 14 void delete_file(void);
 15 
 16 int main(int argc, char **argv)
 17 {
 18     int fd = -1;
 19 
 20     // 打開LOG系統
 21     openlog(argv[0], LOG_PID | LOG_CONS, LOG_USER);
 22     
 23     // 打開文件,不存在則創建,存在則報錯誤提示
 24     fd = open(FILE, O_RDWR | O_TRUNC | O_CREAT | O_EXCL, 0664);
 25     if ( fd < 0 )
 26     {
 27         
 28         if ( errno == EEXIST )
 29         {
 30             printf("%s is running...\n", argv[0]);
 31             _exit(-1);
 32         }
 33     }
 34     syslog(LOG_INFO, "Create file success!");
 35     
 36     // 注冊進程清理函數
 37     atexit(delete_file);    //  Kill -9 PID 後 此函數沒有運行
 38     
 39     close(fd);
 40     closelog();
 41     
 42     // 創建守護進程
 43     create_daemon();
 44     while (1);
 45     
 46     return 0;
 47 }
 48 
 49 // create_daemon() 創建守護進程
 50 void create_daemon(void)
 51 {
 52     int i = 0, cnt = 0;
 53     pid_t pid = -1;
 54     
 55     pid = fork();
 56     if ( -1 == pid)
 57     {
 58         perror("fork");
 59         _exit(-1);
 60     }
 61     if ( pid > 0 )
 62     {
 63         // 子進程等待父進程退出
 64         _exit(0);
 65     }
 66     
 67     /* 此處是子進程執行 */
 68     // setsid() 子進程創建新的會話期,脫離控制台
 69     pid = setsid();
 70     if ( -1 == pid )
 71     {
 72         perror("setsid");
 73         _exit(-1);
 74     }
 75     
 76     // chdir() 調用此函數將當前工作目錄設置為/
 77     chdir("/");
 78     
 79     // umask() 設置為0以取消任何文件權限屏蔽
 80     umask(0);
 81     
 82     // 關閉所有文件描述符
 83     // sysconf() 獲取當前系統中文件描述符的最大數目
 84     cnt = sysconf(_SC_OPEN_MAX);
 85     for ( i = 0; i < cnt; i++ )
 86     {
 87         close(i);
 88     }
 89     
 90     // 將0、1、2定位到/dev/null
 91     open("/dev/null", O_RDWR);
 92     open("/dev/null", O_RDWR);
 93     open("/dev/null", O_RDWR);
 94 }
 95 
 96 // 刪除文件
 97 void delete_file(void)
 98 {
 99     remove(FILE);
100 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved