Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1136892
  • 博文数量: 300
  • 博客积分: 37
  • 博客等级: 民兵
  • 技术积分: 772
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-26 04:46
文章分类
文章存档

2017年(4)

2016年(7)

2015年(19)

2014年(72)

2013年(71)

2012年(127)

分类:

2012-09-24 22:20:52



有个普遍的公约被UNIX系统里的守护进程遵守。


1、如果守护进程使用一个锁文件,那么文件通常存储在/var/run下。然而,注 意,守护进程可能需要超级用户权限在这里创建一个文件。文件名通常是name.pid,这里name是守护进程或服务的名字。例如,cron守护进程的锁 文件是/var/run/crond.pid。


2、如果守护进程支持配置选项,那么它们通常被存储在/etc里。配置文件命名为name.conf,这里name是守护进程或服务的名字。例如,syslogd守护进程的配置为/etc/syslog.conf。


3、守护进程可以通过命令行启动,但是它们通常从系统初始化脚本(/etc/rc*或/etc/init.d/*)来启动。如果守护进程应该在它退出时自动重启,那么我们可以安排init来重启它,如果我们为它在/etc/inittab里包含一个respwan项。


4、 如果守护进程有一个配置文件,那么守护进程在启动时读它,但是通常不会再次看它。如果管理员改变了配置文件,那么守护进程需要停止并重启来使配置改变生 效。为了避免这个,有些守护进程将捕获SIGHUP并在收到这个信号时重新读取它们的配置文件。因为它们不和终端关联,且不是无控制终端的会话领导,就是 孤立线程组的成员,所以守护进程没有理由期望收到SIGHUP。因此,它们可以安全地重用它。



  1. #include <pthread.h>
  2. #include <syslog.h>
  3. #include <signal.h>

  4. sigset_t mask;

  5. extern int already_running(void);

  6. void
  7. reread(void)
  8. {
  9.     /* ... */
  10. }

  11. void *
  12. thr_fn(void *arg)
  13. {
  14.     int err, signo;
  15.     
  16.     for (;;) {
  17.         err = sigwait(&mask, &signo);
  18.         if (err != 0) {
  19.             syslog(LOG_ERR, "sigwait failed");
  20.             exit(1);
  21.         }

  22.         switch (signo) {
  23.         case SIGHUP:
  24.             syslog(LOG_INFO, "Re-reading configuration file");
  25.             reread();
  26.             break;
  27.         
  28.         case SIGTERM:
  29.             syslog(LOG_INFO, "got SIGTERM; exiting");
  30.             exit(0);

  31.         default:
  32.             syslog(LOG_INFO, "unexpected signal %d\n", signo);
  33.         }
  34.     }
  35.     return(0);
  36. }

  37. int
  38. main(int argc, char *argv[])
  39. {
  40.     int err;
  41.     pthread_t tid;
  42.     char *cmd;
  43.     struct sigaction sa;

  44.     if ((cmd = strrchr(argv[0], '/')) == NULL)
  45.         cmd = argv[0];
  46.     else
  47.         cmd++;

  48.     /*
  49.      * Become a daemon.
  50.      */
  51.     daemonize(cmd);

  52.     /*
  53.      * Make sure only one copy of the daemon is running.
  54.      */
  55.     if (already_running()) {
  56.         syslog(LOG_ERR, "daemon already running");
  57.         exit(1);
  58.     }

  59.     /*
  60.      * Restore SIGHUP default and block all signals.
  61.      */
  62.     sa.sa_handler = SIG_DFL;
  63.     sigemptyset(&sa.sa_mask);
  64.     sa.sa_flags = 0;
  65.     if (sigaction(SIGHUP, &sa, NULL) < 0) {
  66.         printf("%s: can't restore SIGHUP default\n", strerror(err));
  67.         exit(1);
  68.     }
  69.     sigfillset(&mask);
  70.     if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0) {
  71.         printf("SIG_BLOCK error: %s\n", strerror(err));
  72.         exit(1);
  73.     }

  74.     /*
  75.      * Create a thread to handle SIGHUP and SIGTERM.
  76.      */
  77.     err = pthread_create(&tid, NULL, thr_fn, 0);
  78.     if (err != 0) {
  79.         printf("can't create thread: %s\n", strerror(err));
  80.         exit(1);
  81.     }

  82.     /*
  83.      * Proceed with the rest of the daemon.
  84.      */
  85.     exit(0);
  86. }

在初始化守护进程后,我们为SIGHUP和SIGTERM安装了信号处理机。我们可以在信号处理机里放置重新读的逻辑,或只在处理机里放置一个标志并让守护进程的主线程做所有的工作。
阅读(869) | 评论(0) | 转发(0) |
0

上一篇:深入理解 Daemon

下一篇:守护进程编程

给主人留下些什么吧!~~