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 }