setsid
实现。前面提到,守护进程是没有控制终端的,显然无法将自己的消息输出到标准输出或标准错误上。而且系统中运行着许多守护进程,因此需要一个集中的守护进程记录设施,即syslog
。
如上图所示,主要有3中产生日志消息的方式:
而syslogd守护进程接收这些日志消息,在其启动前会读取配置文件(/etc/syslog.conf),以决定各类消息的处理方式。
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
// Returns: previous log priority mask value
int setlogmask(int maskpri);
注:在没有调用openlog
的情况下,先调用了syslog
,会自动调用openlog
。
ident
参数指向的字符串会被加到日志消息中去,因此一般指定为程序名称。
option
参数指定各种选项的位屏蔽,选项见图13.3。
facility
参数可选值见图13.4。
priority
参数包含facility和level(图13.5)的组合,如果参数中没有指定facility,则会使用openlog
中指定的facility,如果没有调用openlog
,那么会使用默认值LOG_USER
。
可以按照如下步骤编写一个守护进程。
umask
函数将文件模式创建屏蔽字设置为指定值(通常为0)。守护进程可能需要创建一些文件,如果使用继承的屏蔽字,可能文件的权限会不符合预期。fork
后,使父进程exit
。这样可以保证子进程不是进程组的组长进程。setsid
创建新会话。这可以保证当前进程没有控制终端,且成为新会话的首进程和新进程组的组长进程。getrlimit
函数获取最高文件描述符值,并关闭直到该值的所有描述符。某些守护进程在同一时刻只能运行一个实例程序,这时候可以使用文件和记录锁(下文简称文件锁,详见14章)来实现这个功能。
守护进程只要创建一个固定名字的文件(一般在/var/run目录中),并在该文件整体上加一把写锁,那么此后其他的守护进程如果想要给该文件加锁就会失败,也就不应该继续运行。在守护进程终止时,锁会被自动删除,简化了复原过程。
原文:https://www.cnblogs.com/maxiaowei0216/p/14250313.html