写在前面
在初次接触时,书上介绍了守护进程的特征,然而我并不清楚守护进程具体在Linux中起到什么作用,在网上查了一些资料之后,才理解的更清楚一点。所以,要踏实的学习,有不懂的及时解决~~
一、五个问题+一个实例
总结了本章所讲的内容,可以压缩成五个问题和一个实例,解决了这五个就OK了
1、什么是守护进程?相比普通的进程有什么特征,在Linux中一般起到什么作用?
2、如何确保守护进程无终端?(切断与终端联系)
3、出错消息如何记录,如何表现?
4、单实例守护进程的应用场景,如何保证单实例?
5、客户进程-服务器进程模型概念?
在最后,针对用户编写的守护进程,给出实例。实例链接:https://blog.youkuaiyun.com/vainfanfan/article/details/85251099
二、守护进程基本概念
守护进程(daemon)生存期长,常在系统引导装入时启动,在系统关闭时停止。通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。大多数守护进程是以root权限运行的。
守护进程又可分为用户守护进程和内核守护进程。可从以下特点区分:
1.父进程ID
内核守护进程父进程ID是0。
用户守护进程的父进程ID都是1(init进程)
注意:init父进程ID也是0,但它是内核在引导装入后启动的用户层次的进程。即init父进程ID为0,但它是用户级进程。
2、无终端实现方式
内核守护进程以无终端方式启动,用户守护进程可以使用setsid函数。
在Linux实际环境中,使用命令ps -axj查看进程状态:
fairy@ubuntu:~$ ps -axj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
0 1 1 1 ? -1 Ss 0 0:04 /sbin/init auto noprompt
0 2 0 0 ? -1 S 0 0:00 [kthreadd]
2 3 0 0 ? -1 S 0 0:00 [ksoftirqd/0]
2 4 0 0 ? -1 S 0 0:00 [kworker/0:0]
2 5 0 0 ? -1 S< 0 0:00 [kworker/0:0H]
2 6 0 0 ? -1 S 0 0:00 [kworker/u256:0]
2 7 0 0 ? -1 S 0 0:00 [rcu_sched]
2 8 0 0 ? -1 S 0 0:00 [rcu_bh]
2 9 0 0 ? -1 S 0 0:00 [migration/0]
2 10 0 0 ? -1 S 0 0:00 [watchdog/0]
2 11 0 0 ? -1 S 0 0:00 [watchdog/1]
2 12 0 0 ? -1 S 0 0:00 [migration/1]
2 13 0 0 ? -1 S 0 0:00 [ksoftirqd/1]
2 14 0 0 ? -1 S 0 0:00 [kworker/1:0]
2 15 0 0 ? -1 S< 0 0:00 [kworker/1:0H]
2 16 0 0 ? -1 S 0 0:00 [kdevtmpfs]
1 338 338 338 ? -1 Ssl 0 0:00 vmware-vmblock-fuse /run/vmblock-fuse -o rw,subtype=vmware-v
1 352 352 352 ? -1 Ss 0 0:00 /lib/systemd/systemd-udevd
2 414 0 0 ? -1 S 0 0:00 [kworker/1:3]
1 486 486 486 ? -1 Ssl 100 0:00 /lib/systemd/systemd-timesyncd
1 795 795 795 ? -1 Ssl 0 0:00 /usr/bin/vmtoolsd
1 804 804 804 ? -1 Ss 0 0:00 /usr/sbin/cron -f
1 808 808 808 ? -1 Ss 0 0:00 /usr/sbin/acpid
1 809 809 809 ? -1 Ss 111 0:00 avahi-daemon: running [ubuntu.local]
1 816 816 816 ? -1 Ssl 104 0:00 /usr/sbin/rsyslogd -n
1 819 819 819 ? -1 Ssl 0 0:00 /usr/lib/accountsservice/accounts-daemon
1 829 829 829 ? -1 Ss 0 0:00 /usr/sbin/cupsd -l
1 830 830 830 ? -1 Ss 0 0:00 /lib/systemd/systemd-logind
1 831 831 831 ? -1 Ssl 0 0:00 /usr/sbin/thermald --no-daemon --dbus-enable
这是截取了一部分,主要父进程有三个,0、1、2,首先init和kthreadd由进程0创建,init作为大部分用户级守护进程的父进程,kthreadd作为大部分内核级守护进程的父进程。
然而,到这里,我对守护进程大致有了一个印象,它是处于后台运行的,并且无终端,分用户进程和内核进程,在系统中存活周期长。然而,守护进程能起到什么作用呢?
三、如何实现用户守护进程无终端?
我们在使用守护进程时,主要是在用户空间运行的,所以重点考虑用户守护进程。
其中一种方法是调用setsid函数,建立一个新会话。先决条件是调用进程不是一个进程组的组长进程。(组长进程ID=进程组ID)
具体步骤是:
1.调用fork,父进程exit
原因:(1)如果守护进程是shell启动的,父进程终止会使得shell认为命令已经执行完毕,子进程就可在后台运行。
(2)子进程继承了父进程的进程组ID,但又新建了一个进程ID,保证子进程不是一个进程组的组长ID
2.调用setsid,创建一个新会话
创建成功,则(1)该进程成为一个新的会话首进程和进程组长
(2)与原来的会话和进程脱离,切断与原终端的联系
3.再次调用fork,父进程exit
新的子进程与原有的终端切断联系,但是作为会话首ID,可以申请终端。为了去除这种可能性,创建该会话的第二个进程,首进程退出,第二个进程不具备申请终端权限
四、出错消息记录
由于守护进程没有终端控制,则不能简单的显示标准错误。那写在记录文件中呢,如果每一个守护进程都将出错消息写到单个文件上,则大量的文件管理又成了难题。那么,是使用什么来集中的管理守护进程出错记录的?
在用户进程,使用syslog产生日志消息,消息被发送至UNIX域数据报套接字/dev/log。出错消息主要由syslog管理。
五、单实例守护进程
对于有些设备,在操作时,只允许一个守护进程访问,此时就需满足单实例,实现方式是文件加记录锁。对于每一个守护进程,都有对应的文件,当守护进程运行时,便对记录文件加写锁,结束时释放写锁。如果此时再有同样第二个进程对记录文件加锁,则陷入阻塞状态。
六、客户进程-服务器进程模型
可以将用户进程视为客户进程,守护进程视为服务器进程。当有用户进程请求守护进程时,便得到守护进程的响应。但这种通信是单向的。