Linux Deamon守护进程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或者等待处理某些事件的发生。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。
守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户(root)权限运行,因为它们要使用特殊的端口(1-1024)或访问某些特殊的资源。
一个守护进程的父进程是init进程,因为它真正的父进程在fork出子进程后就先于子进程exit退出了,所以它是一个由init继承的孤儿进程。守护进程是非交互式程序,没有控制终端,所以任何输出,无论是向标准输出设备stdout还是标准出错设备stderr的输出都需要特殊处理。
守护进程的名称通常以d结尾,比如sshd、xinetd(管理网络相关服务)、crond等。
1 守护进程特点
2 查看守护进程
[root@localhost 5.10]# ps axj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
0 1 1 1 ? -1 Ss 0 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
0 2 0 0 ? -1 S 0 0:00 [kthreadd]
2 3 0 0 ? -1 S 0 0:00 [ksoftirqd/0]
2 5 0 0 ? -1 S< 0 0:00 [kworker/0:0H]
2 6 0 0 ? -1 S 0 0:00 [kworker/u2:0]
2 7 0 0 ? -1 S 0 0:00 [migration/0]
2 8 0 0 ? -1 S 0 0:00 [rcu_bh]
2 9 0 0 ? -1 R 0 0:00 [rcu_sched]
2 10 0 0 ? -1 S 0 0:00 [watchdog/0]
2 12 0 0 ? -1 S 0 0:00 [kdevtmpfs]
2 13 0 0 ? -1 S< 0 0:00 [netns]
2 14 0 0 ? -1 S 0 0:00 [khungtaskd]
2 15 0 0 ? -1 S< 0 0:00 [writeback]
2 16 0 0 ? -1 S< 0 0:00 [kintegrityd]
2 17 0 0 ? -1 S< 0 0:00 [bioset]
2 18 0 0 ? -1 S< 0 0:00 [kblockd]
2 19 0 0 ? -1 S< 0 0:00 [md]
2 20 0 0 ? -1 R 0 0:00 [kworker/0:1]
2 25 0 0 ? -1 S 0 0:00 [kswapd0]
......
855 969 969 969 ? -1 Ss 0 0:00 sshd: root@pts/0
969 973 973 973 pts/0 1004 Ss 0 0:00 -bash
2 1002 0 0 ? -1 S 0 0:00 [kworker/0:2]
2 1003 0 0 ? -1 S 0 0:00 [kworker/0:0]
973 1004 1004 973 pts/0 1004 R+ 0 0:00 ps axj
从上面结果看出,TTY表示控制终端,可以看到这几个守护进程的控制终端为"?",意思是这几个守护进程没有控制终端。UID为0,表示进程的启动者是超级进程。
3 守护进程的启动方式
4 编写守护进程的步骤
-
创建子进程,父进程退出
-
在子进程中创建新对话
-
改变当前目录为根目录
-
重设文件权限掩码
-
关闭文件描述符
-
守护进程退出处理
二 实战——隔10秒在/tmp/dameon.log中写入一句话
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/stat.h>
#define MAXFILE 65535
volatile sig_atomic_t _running = 1;
void sigterm_handler(int arg)
_running = 0;
int main()
pid_t pc;
int i, fd, len;
char *buf = "this is a Dameon\n";
len = strlen(buf);
pc = fork(); //第一步
if(pc < 0)
printf("error fork\n");
exit(1);
else if(pc > 0)
exit(0);
setsid(); //第二步
chdir("/"); //第三步
umask(0); //第四步
for(i = 0 ; i < MAXFILE ; i++) //第五步
close(i);
signal(SIGTERM, sigterm_handler);
while(_running)
if((fd = open("/tmp/dameon.log", O_CREAT | O_WRONLY | O_APPEND, 0600)) < 0) \
perror("open");
exit(1);
write(fd, buf, len + 1);
close(fd);
usleep(10 * 1000); //10毫秒
2 编译运行
[root@localhost 5.11]# g++ -o test test.cpp
[root@localhost 5.11]# ll
total 16
-rwxr-xr-x. 1 root root 9208 Mar 31 16:01 test
-rw-r--r--. 1 root root 978 Mar 24 13:11 test.cpp
[root@localhost 5.11]# ./test
[root@localhost 5.11]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1042 1 0 16:18 ? 00:00:01 ./test
root 1045 2 0 16:20 ? 00:00:00 [kworker/0:3]
root 1047 973 0 16:21 pts/0 00:00:00 ps -ef
[root@localhost 5.11]# vi /tmp/dameon.log
this is a Dameon
^@this is a Dameon
^@this is a Dameon
^@this is a Dameon
^@this is a Dameon
^@this is a Dameon
^@this is a Dameon
^@this is a Dameon
^@this is a Dameon
^@this is a Dameon
[root@localhost 5.11]# kill -9 1042
自定义调试信息的输出
调试信息的输出方法有很多种, 例如直接用printf, 或者出错时使用perror, fprintf等将信息直接打印到终端上, 在Qt上面一般使用qDebug,而守护进程则一般是使用syslog将调试信息输出到日志文件中等等…
使用标准的方法打印调试信息有时候不是很方便, 例如Qt编程, 在调试已有的代码时, 我想在打印调试信息的地方, 把代码位置也打印出来以方便定位错误, 或者需要在调试信息前面加一个前辍, 好方便在调试信息太多的时候可以用grep过滤一下, 仅显示本模块的调试信息, 这时需要一个一个地修改已有的qDebug, 使其成为以下形式:
守护进程-----也就是常说的Daemon进程,是linux后台的服务进程,是一个生存期较长的进程,独立于终端并且周期性的执行某种任务或等待处理某些任务。守护进程在系统引 导时载入时启动,在系统关闭时终止。linux下的许多系统服务都是守护进程完成的。守护进程还能完成许多系统任务,如作业规划进程crond,打印进程lqd(d就是
所谓进程守护,就是A进程为了保护自己不被结束,创建了一个守护线程来保护自己,一旦被结束进程,便重新启动。进程守护的方法多被应用于恶意软件,是一个保护自己进程的一个简单方式,在ring3下即可轻松实现。而创建守护线程的方法多采用远程线程注入的方式,笔者之前曾介绍过远程线程注入的基本方式,主要分为DLL远程注入和无DLL远程注入。
///////////////////...
#include <iostream>
LPCTSTR szAppClassName = TEXT("Print Service");
LPCTSTR szAppWindowName = TEXT("Print Service");
using namespace std;
//隐藏DOS黑窗口.