有个普遍的公约被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。因此,它们可以安全地重用它。
- #include <pthread.h>
- #include <syslog.h>
- #include <signal.h>
- sigset_t mask;
- extern int already_running(void);
- void
- reread(void)
- {
- /* ... */
- }
- void *
- thr_fn(void *arg)
- {
- int err, signo;
-
- for (;;) {
- err = sigwait(&mask, &signo);
- if (err != 0) {
- syslog(LOG_ERR, "sigwait failed");
- exit(1);
- }
- switch (signo) {
- case SIGHUP:
- syslog(LOG_INFO, "Re-reading configuration file");
- reread();
- break;
-
- case SIGTERM:
- syslog(LOG_INFO, "got SIGTERM; exiting");
- exit(0);
- default:
- syslog(LOG_INFO, "unexpected signal %d\n", signo);
- }
- }
- return(0);
- }
- int
- main(int argc, char *argv[])
- {
- int err;
- pthread_t tid;
- char *cmd;
- struct sigaction sa;
- if ((cmd = strrchr(argv[0], '/')) == NULL)
- cmd = argv[0];
- else
- cmd++;
- /*
- * Become a daemon.
- */
- daemonize(cmd);
- /*
- * Make sure only one copy of the daemon is running.
- */
- if (already_running()) {
- syslog(LOG_ERR, "daemon already running");
- exit(1);
- }
- /*
- * Restore SIGHUP default and block all signals.
- */
- sa.sa_handler = SIG_DFL;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if (sigaction(SIGHUP, &sa, NULL) < 0) {
- printf("%s: can't restore SIGHUP default\n", strerror(err));
- exit(1);
- }
- sigfillset(&mask);
- if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0) {
- printf("SIG_BLOCK error: %s\n", strerror(err));
- exit(1);
- }
- /*
- * Create a thread to handle SIGHUP and SIGTERM.
- */
- err = pthread_create(&tid, NULL, thr_fn, 0);
- if (err != 0) {
- printf("can't create thread: %s\n", strerror(err));
- exit(1);
- }
- /*
- * Proceed with the rest of the daemon.
- */
- exit(0);
- }
在初始化守护进程后,我们为SIGHUP和SIGTERM安装了信号处理机。我们可以在信号处理机里放置重新读的逻辑,或只在处理机里放置一个标志并让守护进程的主线程做所有的工作。
阅读(869) | 评论(0) | 转发(0) |