守护进程之单实例



  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <time.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <syslog.h>
  11. /* 创建守护进程函数 */
  12. int daemonize(){
  13. int childpid, fd, fdtablesize;
  14. int error, in, out;
  15. /* 忽略终端I/O信号,STOP信号 */
  16. signal(SIGTTOU, SIG_IGN); /* 后台进程写控制终端 */
  17. signal(SIGTTIN, SIG_IGN); /* 后台进程读控制终端 */
  18. signal(SIGTSTP, SIG_IGN); /* 终端挂起 */
  19. signal(SIGHUP, SIG_IGN); /* 进程组长退出时向所有会议成员发出的 */
  20. /* 父进程退出,子进程成为孤儿进程 */
  21. if (fork()!= 0)
  22. exit( 1);
  23. /* 设置新会话的领头进程,并与原来的登录会话和进程组脱离 */
  24. if (setsid() == -1)
  25. exit( 1);
  26. /* 防止会话组长重新申请控制终端,子进程退出,孙进程没有控制终端了 */
  27. if (fork()!= 0)
  28. exit( 1);
  29. /* 关闭打开的文件描述符,防止资源浪费和防止引起无法预料的错误 */
  30. for (fd = 3, fdtablesize = getdtablesize();fd < fdtablesize;fd++){
  31. close(fd);
  32. }
  33. /* 重定向标准输入/标准输出和标准错误输出 */
  34. error = open( "./stderr", O_WRONLY|O_CREAT|O_APPEND, 0600);
  35. dup2(error, 2);
  36. close(error);
  37. in = open( "./stdin", O_RDONLY|O_CREAT, 0600);
  38. dup2(in, 0);
  39. close(in);
  40. out = open( "./stdout", O_WRONLY|O_CREAT|O_APPEND, 0600);
  41. dup2(out, 1);
  42. close(out);
  43. /* 可以改变工作目录 */
  44. /* chdir("/"); */
  45. /* 重设文件创建掩模 */
  46. umask( 0);
  47. /* 忽略SIGCHLD信号, 防止僵尸进程 */
  48. signal(SIGCHLD, SIG_IGN);
  49. return 0;
  50. }
  51. /* 单实例实现, 成功返回0, 失败程序退出, 打印错误或已运行进程号 */
  52. int already_running(const char *szLockFilePath){
  53. int fd;
  54. char szBuf[ 256] = { 0x00 };
  55. fd = open(szLockFilePath, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
  56. if (fd < 0){
  57. memset(szBuf, 0x00, sizeof(szBuf));
  58. sprintf(szBuf, "open LockFile failed!LockfilePath=[%s]/n", szLockFilePath);
  59. perror(szBuf);
  60. exit( 1);
  61. }
  62. /* 尝试获取文件锁 */
  63. struct flock fl;
  64. memset(&fl, 0x00, sizeof(struct flock));
  65. if (fcntl(fd, F_GETLK, &fl) < 0){
  66. perror( "fcntl get LockState failed!/n");
  67. close(fd);
  68. exit( 1);
  69. }
  70. if (fl.l_type != F_UNLCK){
  71. memset(szBuf, 0x00, sizeof(szBuf));
  72. sprintf(szBuf, "已经有一个运行实例了。进程号为[%ld]/n", ( long)fl.l_pid);
  73. perror(szBuf);
  74. close(fd);
  75. exit( 1);
  76. }
  77. fl.l_whence = SEEK_SET; /* 决定l_start的位置 */
  78. fl.l_start = 0; /* 设置锁定区域开头位置 */
  79. fl.l_len = 0; /* 设置锁定区域长度 */
  80. fl.l_type = F_WRLCK; /* 设置锁定状态为写锁 */
  81. fl.l_pid = getpid(); /* 设置锁进程号 */
  82. /* 阻塞式加锁 */
  83. if (fcntl(fd, F_SETLK, &fl) < 0){
  84. perror( "fcntl set Lockfile failed!/n");
  85. close(fd);
  86. exit( 1);
  87. }
  88. /* 把进程号写入文件 */
  89. ftruncate(fd, 0);
  90. memset(szBuf, 0x00, sizeof(szBuf));
  91. sprintf(szBuf, "%ld", ( long)getpid());
  92. write(fd, szBuf, strlen(szBuf)+ 1);
  93. return 0;
  94. }
  95. int main(void){
  96. time_t now;
  97. daemonize();
  98. already_running( "./MyDaemon.pid");
  99. openlog( "MyMsgDaemon", LOG_CONS | LOG_PID, 0);
  100. syslog(LOG_DEBUG, "守护进程测试/n");
  101. while ( 1){
  102. time(&now);
  103. syslog(LOG_DEBUG, "守护进程测试, 当前时间:[%s]/n", ctime(&now));
  104. sleep( 6);
  105. }
  106. return 0;
  107. }

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <time.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <syslog.h>
  11. /* 创建守护进程函数 */
  12. int daemonize(){
  13. int childpid, fd, fdtablesize;
  14. int error, in, out;
  15. /* 忽略终端I/O信号,STOP信号 */
  16. signal(SIGTTOU, SIG_IGN); /* 后台进程写控制终端 */
  17. signal(SIGTTIN, SIG_IGN); /* 后台进程读控制终端 */
  18. signal(SIGTSTP, SIG_IGN); /* 终端挂起 */
  19. signal(SIGHUP, SIG_IGN); /* 进程组长退出时向所有会议成员发出的 */
  20. /* 父进程退出,子进程成为孤儿进程 */
  21. if (fork()!= 0)
  22. exit( 1);
  23. /* 设置新会话的领头进程,并与原来的登录会话和进程组脱离 */
  24. if (setsid() == -1)
  25. exit( 1);
  26. /* 防止会话组长重新申请控制终端,子进程退出,孙进程没有控制终端了 */
  27. if (fork()!= 0)
  28. exit( 1);
  29. /* 关闭打开的文件描述符,防止资源浪费和防止引起无法预料的错误 */
  30. for (fd = 3, fdtablesize = getdtablesize();fd < fdtablesize;fd++){
  31. close(fd);
  32. }
  33. /* 重定向标准输入/标准输出和标准错误输出 */
  34. error = open( "./stderr", O_WRONLY|O_CREAT|O_APPEND, 0600);
  35. dup2(error, 2);
  36. close(error);
  37. in = open( "./stdin", O_RDONLY|O_CREAT, 0600);
  38. dup2(in, 0);
  39. close(in);
  40. out = open( "./stdout", O_WRONLY|O_CREAT|O_APPEND, 0600);
  41. dup2(out, 1);
  42. close(out);
  43. /* 可以改变工作目录 */
  44. /* chdir("/"); */
  45. /* 重设文件创建掩模 */
  46. umask( 0);
  47. /* 忽略SIGCHLD信号, 防止僵尸进程 */
  48. signal(SIGCHLD, SIG_IGN);
  49. return 0;
  50. }
  51. /* 单实例实现, 成功返回0, 失败程序退出, 打印错误或已运行进程号 */
  52. int already_running(const char *szLockFilePath){
  53. int fd;
  54. char szBuf[ 256] = { 0x00 };
  55. fd = open(szLockFilePath, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
  56. if (fd < 0){
  57. memset(szBuf, 0x00, sizeof(szBuf));
  58. sprintf(szBuf, "open LockFile failed!LockfilePath=[%s]/n", szLockFilePath);
  59. perror(szBuf);
  60. exit( 1);
  61. }
  62. /* 尝试获取文件锁 */
  63. struct flock fl;
  64. memset(&fl, 0x00, sizeof(struct flock));
  65. if (fcntl(fd, F_GETLK, &fl) < 0){
  66. perror( "fcntl get LockState failed!/n");
  67. close(fd);
  68. exit( 1);
  69. }
  70. if (fl.l_type != F_UNLCK){
  71. memset(szBuf, 0x00, sizeof(szBuf));
  72. sprintf(szBuf, "已经有一个运行实例了。进程号为[%ld]/n", ( long)fl.l_pid);
  73. perror(szBuf);
  74. close(fd);
  75. exit( 1);
  76. }
  77. fl.l_whence = SEEK_SET; /* 决定l_start的位置 */
  78. fl.l_start = 0; /* 设置锁定区域开头位置 */
  79. fl.l_len = 0; /* 设置锁定区域长度 */
  80. fl.l_type = F_WRLCK; /* 设置锁定状态为写锁 */
  81. fl.l_pid = getpid(); /* 设置锁进程号 */
  82. /* 阻塞式加锁 */
  83. if (fcntl(fd, F_SETLK, &fl) < 0){
  84. perror( "fcntl set Lockfile failed!/n");
  85. close(fd);
  86. exit( 1);
  87. }
  88. /* 把进程号写入文件 */
  89. ftruncate(fd, 0);
  90. memset(szBuf, 0x00, sizeof(szBuf));
  91. sprintf(szBuf, "%ld", ( long)getpid());
  92. write(fd, szBuf, strlen(szBuf)+ 1);
  93. return 0;
  94. }
  95. int main(void){
  96. time_t now;
  97. daemonize();
  98. already_running( "./MyDaemon.pid");
  99. openlog( "MyMsgDaemon", LOG_CONS | LOG_PID, 0);
  100. syslog(LOG_DEBUG, "守护进程测试/n");
  101. while ( 1){
  102. time(&now);
  103. syslog(LOG_DEBUG, "守护进程测试, 当前时间:[%s]/n", ctime(&now));
  104. sleep( 6);
  105. }
  106. return 0;
  107. }

猜你喜欢

转载自blog.csdn.net/iot_shun/article/details/81026973