linux守护进程 daemon,Linux 下创建简单的守护进程(Daemon)

守护进程运行在背景,其父进程 pid=1(init/systemd). 创建守护进程的主要思路,就是 fork 一个子进程,然后父进程挂掉让子进程变为孤儿,最终孤儿被 pid=1 的进程领养。

Daemon 的创建步骤 (SysV)

1. Fork

fork off the parent process & let it terminate if forking was successful. -> Because the parent process has terminated, the child process now runs in the background.

2. Setsid

setsid - Create a new session. The calling process becomes the leader of the new session and the process group leader of the new process group. The process is now detached from its controlling terminal (CTTY).

3. Signal

Catch signals - Ignore and/or handle signals.

4. Fork again

fork again & let the parent process terminate to ensure that you get rid of the session leading process. (Only session leaders may get a TTY again.)

5. chdir

chdir - Change the working directory of the daemon.

6. umask

umask - Change the file mode mask according to the needs of the daemon.

7. Close FDs

close - Close all open file descriptors that may be inherited from the parent process.

引用 Pascal Werkl 的示例代码:

//By Pascal Werkl

/*

* daemonize.c

* This example daemonizes a process, writes a few log messages,

* sleeps 20 seconds and terminates afterwards.

*/

#include #include #include #include #include #include #include static void skeleton_daemon()

{

pid_t pid;

/* Fork off the parent process */

pid = fork();

/* An error occurred */

if (pid < 0)

exit(EXIT_FAILURE);

/* Success: Let the parent terminate */

if (pid > 0)

exit(EXIT_SUCCESS);

/* On success: The child process becomes session leader */

if (setsid() < 0)

exit(EXIT_FAILURE);

/* Catch, ignore and handle signals */

//TODO: Implement a working signal handler */

signal(SIGCHLD, SIG_IGN);

signal(SIGHUP, SIG_IGN);

/* Fork off for the second time*/

pid = fork();

/* An error occurred */

if (pid < 0)

exit(EXIT_FAILURE);

/* Success: Let the parent terminate */

if (pid > 0)

exit(EXIT_SUCCESS);

/* Set new file permissions */

umask(0);

/* Change the working directory to the root directory */

/* or another appropriated directory */

chdir("/");

/* Close all open file descriptors */

int x;

for (x = sysconf(_SC_OPEN_MAX); x>0; x--)

{

close (x);

}

/* Open the log file */

openlog ("firstdaemon", LOG_PID, LOG_DAEMON);

}

int main()

{

skeleton_daemon();

while (1)

{

//TODO: Insert daemon code here.

syslog (LOG_NOTICE, "First daemon started.");

sleep (20);

break;

}

syslog (LOG_NOTICE, "First daemon terminated.");

closelog();

return EXIT_SUCCESS;

}

Linux 中的 daemon()调用

在 Linux 中,我们可以调用 daemon() 来创建守护进程。不过该方法并非 POSIX 定义,所以如果代码需要在非 Linux 平台运行,可能会出现与 Linux 平台不一致的行为。

The daemon function is not defined in POSIX, so its implementation (if any) could behave differently on different platforms.

On Linux with glibc, daemon only does one fork, optionally chdirs (but only to /, you can't specify a path), does not touch umask, and does not close the std* descriptors (it optionally reopens them to /dev/null though). (source)

So it depends on the platform, and at least one implementation does less than what you do. If you need all of what you're doing, stick with that (or stick to a platform where the daemon function does exactly that).

#include #include #include #include #include #include #include int main()

{

daemon(0,0);

openlog ("linuxdaemon", LOG_PID, LOG_DAEMON);

while (1)

{

//TODO: Insert daemon code here.

syslog (LOG_NOTICE, "First daemon started.");

sleep (20);

break;

}

syslog (LOG_NOTICE, "First daemon terminated.");

closelog();

return EXIT_SUCCESS;

}

Systemd 的 daemon

Systemd 有自己的一套 Systemd-style daemon, 据说是为了加快服务启动速度而设计的。关于 Systemd 的守护进程,可以参考 man daemon (在 RHEL7/CentOS7 可以 man 到一篇很详细的文档。)

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值