linux下使用daemon函数编写后台程序,在Linux下编写Daemon

最简单的可以使用nohup

Linux下的Daemon简介

1、Service就是指常驻内存大一些程序,且可以提供一些系统或是网络功能。提供service的那个程序就成为daemon。Daemon和service可以视为等同,不必刻意去区分。

2、Daemon可以分为两类,一类是可独立启动的,成为stand alone;另一类是通过一支super daemon来统一管理的服务。

3、Stand alone类型的daemon能够自动启动,常驻内存,对请求响应较快,如httpd、vsftpd等。

4、Super daemon统一管理的是用户有请求,super daemon就唤醒响应daemon,如果用户请求结束,就kill掉该daemon。优点不用常驻内存,缺点装到内存需要时间。如telnet。这个super daemon早期是inetd,后来被xinetd取代。

5、Super daemon与stand alone daemon的形象比喻:stand alone就像银行的专用窗口,某些窗口专门负责取钱,某些窗口专门负责兑换外币;super daemon就是一个综合性窗口,什么业务都受理。

6、Linux中,daemon的命名规则通常是在所提供的服务名后面加d,如httpd。

7、/etc/services文件中记录了service与port的对应关系。是网络服务文件,使用服务名称、端口名、协议名、以及别名来表示。

8、Linux的端口号范围为0~65535:0,不适用;1-1023系统保留只能由root使用;1024-4999,客户端程序自由分配,5000-65535服务器端程序自由分配。

9、一般的启动与关闭daemon都是写成一个shell script来完成。

10、系统服务启动的script几乎全是放到/etc/init.d/目录下。CentOS实际上放到/etc/rc.d/init.d/中的,但是跟/etc/init.d/下一样,做了链接。

11、几乎所有服务的初始化设定文档都是放在/etc/sysconfig/目录下,网络的初始化配置卸载/etc/sysconfig/network这个文件中。

12、Super daemon的主要设定档写在/etc/xinetd.conf,它所管理的其它的daemon的设定档卸载/etc/xinetd.d/目录下。

13、各服务的设定档都是放在/etc/目录下。

14、/var/lib/放的都是各服务产生的数据。

15、/var/run/放的是各服务的程序之PID记录处。

17、除了16中所描述的使用/etc/init.d/目录下的shell script来管理服务,启动关闭daemon以外,可以使用service这个script(可以直接查看/sbin/service这个文件,纯文本写成的script)来管理daemon,service这个script可以分析service后面的参数,到/etc/init.d/下去取得正确的服务来start或stop。如下:

18、Super daemon本身也是一支stand alone的daemon。

Linux(以Redhat Linux Enterprise Edition

5.3为例)下,有时需要编写Service。Service也是程序,一般随系统启动用户不干预就不退出的程序,可以称为Service。Linux下

的Service一般称为Daemon。

以上是广义的Service的定义。Linux下的Service一般放在/etc/init.d文件夹下。浏览一下这个文件夹下的文件,可以发现在Linux下编写Service一般遵循的原则。

一 Linux下编写Service一般遵循的原则

1)真正运行的Service一般放在某个bin目录下(/bin,/usr/bin,etc)。

2)/etc/init.d文件夹下一般是shell脚本,用来控制bin目录下的Service。

3)/etc/init.d文件夹下的shell脚本一般接受至少两个参数,start和stop。还有其他常用的可选参数如status,reload,restart,等。

4)/etc/init.d文件夹下的shell脚本至少包括两行注释,一行告诉chkconfig此服务运行的runlevel,启动优先级,结束优先级。一行告诉chkconfig此服务的描述。

二 Linux的启动过程和RunLevel

理解Linux的启动过程和RunLevel,可以先浏览一下/etc/inittab文件。在/etc/inittab中定义了下面7种

RunLevel。每个Service可以设置自己在哪个RunLevel下运行。可以调用/sbin/init

进入相应的RunLevel,比如运行/sbin/init

6就会导致系统重启。如果在某个RunLevel下某个服务不能启动,导致系统启动失败,可以进入没有配置此服务的RunLevel来禁用或修改此服务

(有点类似Windows下的安全模式)。

#   0 - halt (Do NOT set initdefault to this)

#   1 - Single user mode

#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)

#   3 - Full multiuser mode

#   4 - unused

#   5 - X11

#   6 - reboot (Do NOT set initdefault to this)

/etc/inittab文件下还定义了缺省RunLevel。如下,代表缺省RunLevel是5。

id:5:initdefault:

在/etc文件夹下,执行ls -d rc*,会列出下面这些文件和目录:

rc  rc0.d  rc1.d  rc2.d  rc3.d  rc4.d  rc5.d  rc6.d  rc.d  rc.local  rc.sysinit

rc是一个脚本,在/etc/inittab中,会根据RunLevel执行rc 。rc脚本会到相应的rcN.d中去执行下面的脚本。rc.local是最后调用的脚本,可以放一些用户自定义的任务在里面。

入rcN.d文件夹下,会发现以S和K开头的脚本的链接,S和K后面还带2位数字。其中S代表Start,K代表Kill。S开头的脚本,在rc中调用的

时候会带start参数;K开头的脚本,在rc中调用的时候会带stop参数。S和K后面带的2位数字代表Service的优先级,数字越大,越后执行。

这些脚本的链接的目的地多半都在/etc/init.d文件夹下。

在一切都清晰了。我们可以通过在相应的rcN.d文件夹下按既定的规范创建/etc/init.d下脚本的软链接的方式来控制系统启动和退出时服务的启动

和结束。但是用手动的方式创建软链接来管理毕竟不方便,RedHatLinux提供了chkconfig来帮助创建这些软链接。只要放在/etc

/init.d下的服务控制脚本符合前面提到的chkconfig的约定(注释chkconfig 和

description),就可以用chkconfig --add   chkconfig --list

chkconfig --del 等命令来控制service的启动与否。

三 一个例子

1)下面是用c++语言写的一个Service,此Service在/tmp/random文件中,每隔5秒生成一个4位随机数字。通过g++ -o myrand myrand.cpp编译。然后把myrand放到/root/bin/文件夹下。

/* myrand.cpp

* this program read 4 chars from /dev/random in each iteration,

* and then adjust it to 0-9. Finally the 4 chars are written

* to /tmp/random. This is only for testing /dev/random, and

* at the same time serve as a example service.

*/

#include 

#include 

using namespace std;

#include 

int main()

{

while (true)

{

ifstream ifile("/dev/random");

char ch;

char str[5];

str[4]=0;

int i;

for(i=0;i<4;i++)

{

ifile >> ch;

if(ch<0) ch=-ch;

ch = ch % 10;

ch='0' + ch;

str[i]=ch;

}

ofstream ofile("/tmp/random");

ofile <

sleep(5);

}

}

2) 下面是一个脚本,名字是myrandservice,放在/etc/init.d文件夹下:

#!/bin/sh

#

# chkconfig: 2345  80 50

# description: myrandservice is for testing how to write service in Linux

#

# processname: myrandservice

#

# Source function library.

. /etc/rc.d/init.d/functions

ret=0

start() {

# check fdb status

echo "start myrandservice"

daemon /root/bin/myrand &

ret=$?

}

stop() {

echo "stop myrandservice"

kill -9 $(ps -ef | grep myrand | grep -v grep | awk '{print $2}')

ret=$?

}

status() {

local result

echo "check status of myrandservice..."

#lines=$( ps -ef | grep myrand | grep -v grep  |  )

#echo $lines

result=$( ps -ef | grep myrand | grep -v myrandservice | grep -v grep | wc -l )

#echo $result

if [ $result -gt 0 ] ; then

echo "my randservice is up"

ret=0

else

echo "my randservice is down"

ret=1

fi

echo "check status of myrandservice...done."

}

# See how we were called.

case "$1" in

start)

start

;;

stop)

stop

;;

status)

status

;;

*)

echo $"Usage: $0 {start|stop|status}"

exit 1

esac

exit $ret

3)使用/sbin/chkconfig --add myrandservice 来将次daemon设置为自动启动。 同时可以在rc3.d,rc4.d,rc5.d下面看到相应的脚本链接被自动地创建了。

4)例子的一些说明

子中脚本的下面两行既是给chkconfig用的。其中2345代表此服务在RunLevel 2, 3, 4,

5下开启;80代表启动优先级;50代表结束优先级。如果RunLevel处不添值,用“-”代替,则代表此服务在任何runlevel下都不会自动启

动,需要手动启动。可以通过service

start/stop/status等来控制或查询Service。

# chkconfig: 2345  80 50

# description: myrandservice is for testing how to write service in Linux

本中的daemon函数存在于/etc/rc.d/init.d/functions中。daemon会重定向输出到/dev/null,也会设置是否生

成coredump文件。通过daemon启动的程序,即使用户退出了命令行shell,也会保证Service会运行而不会退出。在/etc/rc.d

/init.d/functions中还包括其他一些有用的函数,如killproc,status等,分别用来杀掉服务和查看服务状态。

四 deamon的另一种实现

不使用/etc/rc.d/init.d/functions中的daemon,则Daemon程序设计要遵从以下过程:

(1)程序运行后调用fork,并让父进程退出。子进程获得一个新的进程ID,但继承了父进程的进程组ID。

(2)调用setsid创建一个新的session,使自己成为新session和新进程组的leader,并使进程没有控制终端(tty)。

(3)设置文件创建mask为0,避免创建文件时权限的影响。

(4)关闭不需要的打开文件描述符。因为Daemon程序在后台执行,不需要于终端交互,通常就关闭STDIN、STDOUT和STDERR。其它根据实际情况处理。

(5)Daemon无法输出信息,可以使用SYSLOG或自己的日志系统进行日志处理。(可选)

(6)编写管理Daemon的SHELL脚本,使用service对Daemon进行管理和监控。(可选)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值