- 浏览: 396114 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
surpassno:
南冠楚囚 写道如果是复制一个一位数组,那么改变复制后的数组并不 ...
java的system.arraycopy()方法 -
南冠楚囚:
如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。你 ...
java的system.arraycopy()方法 -
wxq5513866:
有密码,大家不要下载了,下载也解压不了,别上当了
android中调用webservice -
wxq5513866:
happyhan 写道还要密码啊 能否告知密码
android中调用webservice -
happyhan:
还要密码啊 能否告知密码
android中调用webservice
守护进程
守护进程是生存期长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。他们常常在系统引导装入时启动,在系统关闭时终止。unix系统有很多守护进程,大多数服务器都是用守护进程实现的。比如,网络服务inetd、Web服务http等。同时,守护进程完成许多系统任务。比如,作业规划进程crond、打印进程lqd等。
这里主要说明守护进程的进程结构,以及如何编写守护进程程序。因为守护进程没有控制终端,所以我们还要介绍在守护进程运行时错误输出的方法。
守护进程及其特性
守护进程最重要的特性是后台运行。在这一点上,DOS下的常驻内存程序TSR与之相似。
其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符、控制终端、会话和进程组、工作目录以及文件创建掩码等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。
最后,守护进程的启动方式有其特殊之处。它可以在系统启动时从启动脚本/etc/rc.d中启动,可以由inetd守护进程启动,可以有作业规划进程crond启动,还可以由用户终端(通常是shell)执行。
总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。如果大家对进程的认识比较深入,就对守护进程容易理解和编程了。
首先我们来察看一些常用的系统守护进程,看一下他们和几个概念:进程组、控制终端和对话期有什么联系。p s命令打印系统中各个进程的状态。该命令有多个选择项,有关细节请参考系统手册。为了察看所需的信息,执行:
ps –axj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
0 1 0 0 ? -1 S 0 0:04 init
1 2 1 1 ? -1 SW 0 0:00 [keventd]
1 3 1 1 ? -1 SW 0 0:00 [kapm-idled]
0 4 1 1 ? -1 SWN 0 0:00 [ksoftirqd_CPU0]
0 5 1 1 ? -1 SW 0 0:00 [kswapd]
0 6 1 1 ? -1 SW 0 0:00 [kreclaimd]
0 7 1 1 ? -1 SW 0 0:00 [bdflush]
0 8 1 1 ? -1 SW 0 0:00 [kupdated]
1 9 1 1 ? -1 SW< 0 0:00 [mdrecoveryd]
1 17 1 1 ? -1 SW 0 0:02 [kjournald]
1 92 1 1 ? -1 SW 0 0:00 [khubd]
1 573 573 573 ? -1 S 0 0:03 syslogd -r -x
1 578 578 578 ? -1 S 0 0:00 klogd -2
1 598 598 598 ? -1 S 32 0:00 portmap
进程号为1、2的这些进程非常特殊,存在于系统的整个生命期中。它们没有父进程ID ,没有组进程ID ,也没有对话期ID 。syslogd 守护进程可用于任何为操作人员记录系统消息的程序中。可以在一台实际的控制台上打印这些消息,也可将它们写到一个文件中。sendmail 是标准邮递守护进程。update 程序定期将内核缓存中的内容写到硬盘上(通常是每隔30 秒)。为了做到这一点,该程序每隔30 秒调用sync(2 )函数一次。cron 守护进程在指定的日期和时间执行指定的命令。许多系统管理任务是由cron 定期地使相关程序执行而得以实现的。inetd进程监听系统的网络界面,以输入对各种网络服务器的请求。最后一个守护进程,lpd 处理对系统提出的各个打印请求。
注意,所有守护进程都以超级用户(用户ID为0)的优先权运行。没有一个守护进程具有控制终端,终端名称设置为问号(?)、终端前台进程组ID设置为-1。缺少控制终端是守护进程调用了setsid的结果。除update以外的所有守护进程都是进程组的首进程,对话期的首进程,而且是这些进程组和对话期中的唯一进程。最后,应当引起注意的是所有这些守护进程的父进程都是init进程。
在接触实际编程前,我们来看看编写守护进程要碰到的概念:进程组合会话期。
进程组
每个进程除了有一进程ID之外,还属于一个进程组(在讨论信号时就会涉及进程组)进程组是一个或多个进程的集合。每个进程有一个唯一的进程组ID。进程组ID类似于进程ID——它是一个正整数,并可存放在pid_t数据类型中。
每个进程组有一个组长进程。组长进程的标识是,其进程组ID等于其进程ID,进程组组长可以创建一个进程组,创建该组中的进程,然后终止,只要在某个进程组中有一个进程存在,则该进程就存在,这与其组长进程是否终止无关。从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组的生命期。某个进程组中的最后一个进程可以终止,也可以参加另一进程组。
前面已经提到进程调用setgid可以参加一个现存的组或者创建一个新进程组(setsid也可以创建一个新的进程组,后面将用到)
会话期
会话期(session)是一个或多个进程组的集合。其中,在一个会话期中有3个进程组,通常是有shell的管道线将几个进程编成一组的。
下面说明有关会话期和进程组的一些特性:
一个会话期可以有一个单独的控制终端(controlling terminal),这一般是我们在其上登录的终端设备(终端登录)或伪终端设备(网络登录),但这个控制终端并不是必需的。
建立与控制终端连接的会话期首进程,被称之为控制进程(contronlling process)。以及一个会话期中的几个进程组可被分为一个前台进程组(foreground process group)以及一个或几个后台进程组(background process group)
如果一个会话期有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组。无论何时键入中断键(常常是delete或ctrl-c)或退出键(通常是ctrl-\),就会造成将中断信号或退出信号送至前途进程组的所有进程。
守护进程的编程规则
在不同Unix环境下,守护进程的具体编程细节并不一致。但所幸的是,守护进程的编程原则其实都一样,区别仅在于具体的实现细节不同,这个原则就是要满足守护进程的特性。编程规则如下:
1、在后台运行
为避免挂起控制终端,要将daemon放入后台执行,其方法是,在进程中调用fork使父进程终止,让daemon在子进程中后台执行。具体就是调用f o r k ,然后使父进程e x i t 。这样做实现了下面几点:
第一,如果该精灵进程是由一条简单s h e l l 命令起动的,那么使父进程终止使得s h e l l 认为这条命令已经执行完成。
第二,子进程继承了父进程的进程组I D ,但具有一个新的进程I D ,这就保证了子进程不是一个进程组的首进程。这对于下面就要做的s e t s i d 调用是必要的前提条件。
2、脱离控制终端,登录会话和进程组
登录会话可以包含多个进程组,这些进程组共享一个控制终端,这个控制终端通常是创建进程的登录终端、控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。
其方法是在第一点的基础上,调用setsid()使进程成为会话组长:
需要说明的是,当进程是会话组长时,setsid()调用会失败,但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离,由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
具体是操作就是:
(a )成为新对话期的首进程
(b )成为一个新进程组的首进程
(c )没有控制终端。
3、禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长,但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
4、关闭打开的文件描述符
进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在地文件系统无法卸下以及无法预料的错误。一般来说,必要的是关闭0、1、2三个文件描述符,即标准输入、标准输出、标准错误。因为我们一般希望守护进程自己有一套信息输出、输入的体系,而不是把所有的东西都发送到终端屏幕上。调用fclose();
5、改变当前工作目录
将当前工作目录更改为根目录。从父进程继承过来的当前工作目录可能在一个装配的文件系统中。因为精灵进程通常在系统再引导之前是一直存在的,所以如果精灵进程的当前工作目录在一个装配文件系统中,那么该文件系统就不能被拆卸。
另外,某些精灵进程可能会把当前工作目录更改到某个指定位置,在此位置做它们的工作。例如,行式打印机假脱机精灵进程常常将其工作目录更改到它们的s p o o l 目录上。
可以调用chdir(“目录”);
6、重设文件创建掩码
将文件方式创建屏蔽字设置为0 。由继承得来的文件方式创建屏蔽字可能会拒绝设置某些许可权。例如,若精灵进程要创建一个组可读、写的文件,而继承的文件方式创建屏蔽字,屏蔽了这两种许可权,则所要求的组可读、写就不能起作用。
7、处理SIGCHLD 信号
处理SIGCHLD信号并不是必需的。但对于某些进程,特别是服务器进程往往在请求到来时生产子进程出来请求。如果父进程不等待子进程结束,子进程将成为僵尸进程,(zombie)而仍占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在系统V下可以简单的将SIGCHLD信号的操作设为SIG-IGN:
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程,这一点与BSD4不同,在BSD4下必须显示等 待子进程结束才能释放僵尸进程。
守护进程实例
守护进程实例包括两部分:主程序test.c和初始化程序init.c。主程序每隔一分钟向/tmp
目录中的日志test.log 报告运行状态。初始化程序中的init_daemon 函数负责生成守护进程
void make_daemon(void)
{
pid_t pid;
FILE * lockfd;
sigset_t sighup;
int i;
extern pid_t getsid(pid_t);
pid = fork();//第一个子进程生成
if (pid < 0) {
printinfo("fork error!",INFOERROR);
exit(FAILEXIT);
}else if (pid > 0) {
printinfo("fork 1 ok! ", INFOSCREEN);
exit(OKEXIT);//退出父进程,摆脱shell的控制
}
pid = getpid();//获得子进程自身的id
lockfd = fopen(PIDFILE, "w");//以下是将pid写入文件
if (lockfd != NULL) {
fprintf(lockfd, "%d\n", pid);
fclose(lockfd);
}//写入pid
if (getsid(0) != pid) {//创建新的会话期
if (setsid() < 0) {
printinfo("backupdaemon setsid error!",INFOERROR);
perror("setsid");
}
}
if(pid=fork()){//再次生成子进程,这时候是孙子进程
exit(0);//退出上一代进程
}else if(pid<0){
exit(1);
}
close(1);//关闭文件
close(2);
chdir(rundir);//改变运行的目录
umask(022);//改变文件权限
}
守护进程的错误输出
守护进程不属于任何终端,所以当需要输出某些信息时,它无法像一般程序那样将信息直接输出到标准输出和标准错误输出中。我们很大时候也不希望每个守护进程将它自己的出错消息写到一个单独的文件中。因为对于系统管理人员而言,要记住哪一个守护进程写到哪一个记录文件中,并定期的检查这些文件,他一定会为此感到头疼的。所以,我们需要有一个集中的守护进程出错记录机制。目前很多系统都引入了syslog记录进程来实现这一目的。
自伯克利开发了BSD syslog并广泛应用以来,BSD syslog 机制被大多数守护进程所使用。我们下面介绍BSD syslog 的用法。有三种方法产生记录消息:
1 内核例程可以调用log函数。任何一个用户进程通过打开和读/dev/klog设备就可以读取这些消息。因为我们无意编写内核中的例程,所以不再进一步说明此函数。
2 大多数用户进程(守护进程)调用syslog函数以产生记录消息。我们将在下面说明其调用序列。这使消息发送至Unix域数据报套接口/dev/log。
3 在此主机上,或通过TCP/IP网络连接到此主机的某一其他主机上的一个用户进程可将记录消息发向UDP端口514。
注意:syslog 函数并不产生这些UDP数据报——它们要求产生此记录消息的进程具有显式的网络编程。
通常,syslog守护进程读取三种格式的记录消息。此守护进程在启动时读一个配置文件。一般来说,其文件名为/etc/syslog.conf,该文件决定了不同种类的消息应送向何处。例如,紧急消息可被送向系统管理员(若已登录),并在控制台上显示,而警告消息则可记录到一个文件中。该机制提供了syslog函数,其调用格式如下
#include
void openlog (char*ident,int option ,int facility);
void syslog(int priority,char*format,……)
void closelog();
调用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,自动调用openlog。调用closelog也是可选择的,它只是关闭被用于与syslog守护进程通信的描述符。调用openlog 使我们可以指定一个ident,以后, 此ident 将被加至每则记录消息中。ident 一般是程序的名称(例如 ,cron ,inetd 等)。option 有4种可能:
LOG_CONS 若日志消息不能通过Unix域数据报发送至syslog,则将该消息写至控制台。
LOG_NDELAY1 立即打开Unix域数据报套接口至syslog守护进程,而不要等到记录第一消息。通常,在记录第一条消息之前,该套接口不打开。
LOG_PERROR 除将日志消息发送给syslog 外,还将它至标准出错。此选项仅由4.3BSDReno及以后版本支持。
LOG_PID 每条消息都包含进程ID。此选项可供对每个请求都fork一个子进程的守护进程使用。
在openlog中设置facility参数的目的是让配置文件可以说明,来自不同设施的消息以不同的方式进行处理。如果不调用openlog,或者以facility 为0来调用它,那么在调用syslog 时,可将facility作为priority参数的一个部分进行说明。调用syslog产生一个记录消息。其priority参数是facility和level的组合,它们可选取的值分别列于下面。level值按优先级从高级到最低按序排列。
守护进程是生存期长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。他们常常在系统引导装入时启动,在系统关闭时终止。unix系统有很多守护进程,大多数服务器都是用守护进程实现的。比如,网络服务inetd、Web服务http等。同时,守护进程完成许多系统任务。比如,作业规划进程crond、打印进程lqd等。
这里主要说明守护进程的进程结构,以及如何编写守护进程程序。因为守护进程没有控制终端,所以我们还要介绍在守护进程运行时错误输出的方法。
守护进程及其特性
守护进程最重要的特性是后台运行。在这一点上,DOS下的常驻内存程序TSR与之相似。
其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符、控制终端、会话和进程组、工作目录以及文件创建掩码等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。
最后,守护进程的启动方式有其特殊之处。它可以在系统启动时从启动脚本/etc/rc.d中启动,可以由inetd守护进程启动,可以有作业规划进程crond启动,还可以由用户终端(通常是shell)执行。
总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。如果大家对进程的认识比较深入,就对守护进程容易理解和编程了。
首先我们来察看一些常用的系统守护进程,看一下他们和几个概念:进程组、控制终端和对话期有什么联系。p s命令打印系统中各个进程的状态。该命令有多个选择项,有关细节请参考系统手册。为了察看所需的信息,执行:
ps –axj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
0 1 0 0 ? -1 S 0 0:04 init
1 2 1 1 ? -1 SW 0 0:00 [keventd]
1 3 1 1 ? -1 SW 0 0:00 [kapm-idled]
0 4 1 1 ? -1 SWN 0 0:00 [ksoftirqd_CPU0]
0 5 1 1 ? -1 SW 0 0:00 [kswapd]
0 6 1 1 ? -1 SW 0 0:00 [kreclaimd]
0 7 1 1 ? -1 SW 0 0:00 [bdflush]
0 8 1 1 ? -1 SW 0 0:00 [kupdated]
1 9 1 1 ? -1 SW< 0 0:00 [mdrecoveryd]
1 17 1 1 ? -1 SW 0 0:02 [kjournald]
1 92 1 1 ? -1 SW 0 0:00 [khubd]
1 573 573 573 ? -1 S 0 0:03 syslogd -r -x
1 578 578 578 ? -1 S 0 0:00 klogd -2
1 598 598 598 ? -1 S 32 0:00 portmap
进程号为1、2的这些进程非常特殊,存在于系统的整个生命期中。它们没有父进程ID ,没有组进程ID ,也没有对话期ID 。syslogd 守护进程可用于任何为操作人员记录系统消息的程序中。可以在一台实际的控制台上打印这些消息,也可将它们写到一个文件中。sendmail 是标准邮递守护进程。update 程序定期将内核缓存中的内容写到硬盘上(通常是每隔30 秒)。为了做到这一点,该程序每隔30 秒调用sync(2 )函数一次。cron 守护进程在指定的日期和时间执行指定的命令。许多系统管理任务是由cron 定期地使相关程序执行而得以实现的。inetd进程监听系统的网络界面,以输入对各种网络服务器的请求。最后一个守护进程,lpd 处理对系统提出的各个打印请求。
注意,所有守护进程都以超级用户(用户ID为0)的优先权运行。没有一个守护进程具有控制终端,终端名称设置为问号(?)、终端前台进程组ID设置为-1。缺少控制终端是守护进程调用了setsid的结果。除update以外的所有守护进程都是进程组的首进程,对话期的首进程,而且是这些进程组和对话期中的唯一进程。最后,应当引起注意的是所有这些守护进程的父进程都是init进程。
在接触实际编程前,我们来看看编写守护进程要碰到的概念:进程组合会话期。
进程组
每个进程除了有一进程ID之外,还属于一个进程组(在讨论信号时就会涉及进程组)进程组是一个或多个进程的集合。每个进程有一个唯一的进程组ID。进程组ID类似于进程ID——它是一个正整数,并可存放在pid_t数据类型中。
每个进程组有一个组长进程。组长进程的标识是,其进程组ID等于其进程ID,进程组组长可以创建一个进程组,创建该组中的进程,然后终止,只要在某个进程组中有一个进程存在,则该进程就存在,这与其组长进程是否终止无关。从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组的生命期。某个进程组中的最后一个进程可以终止,也可以参加另一进程组。
前面已经提到进程调用setgid可以参加一个现存的组或者创建一个新进程组(setsid也可以创建一个新的进程组,后面将用到)
会话期
会话期(session)是一个或多个进程组的集合。其中,在一个会话期中有3个进程组,通常是有shell的管道线将几个进程编成一组的。
下面说明有关会话期和进程组的一些特性:
一个会话期可以有一个单独的控制终端(controlling terminal),这一般是我们在其上登录的终端设备(终端登录)或伪终端设备(网络登录),但这个控制终端并不是必需的。
建立与控制终端连接的会话期首进程,被称之为控制进程(contronlling process)。以及一个会话期中的几个进程组可被分为一个前台进程组(foreground process group)以及一个或几个后台进程组(background process group)
如果一个会话期有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组。无论何时键入中断键(常常是delete或ctrl-c)或退出键(通常是ctrl-\),就会造成将中断信号或退出信号送至前途进程组的所有进程。
守护进程的编程规则
在不同Unix环境下,守护进程的具体编程细节并不一致。但所幸的是,守护进程的编程原则其实都一样,区别仅在于具体的实现细节不同,这个原则就是要满足守护进程的特性。编程规则如下:
1、在后台运行
为避免挂起控制终端,要将daemon放入后台执行,其方法是,在进程中调用fork使父进程终止,让daemon在子进程中后台执行。具体就是调用f o r k ,然后使父进程e x i t 。这样做实现了下面几点:
第一,如果该精灵进程是由一条简单s h e l l 命令起动的,那么使父进程终止使得s h e l l 认为这条命令已经执行完成。
第二,子进程继承了父进程的进程组I D ,但具有一个新的进程I D ,这就保证了子进程不是一个进程组的首进程。这对于下面就要做的s e t s i d 调用是必要的前提条件。
2、脱离控制终端,登录会话和进程组
登录会话可以包含多个进程组,这些进程组共享一个控制终端,这个控制终端通常是创建进程的登录终端、控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。
其方法是在第一点的基础上,调用setsid()使进程成为会话组长:
需要说明的是,当进程是会话组长时,setsid()调用会失败,但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离,由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
具体是操作就是:
(a )成为新对话期的首进程
(b )成为一个新进程组的首进程
(c )没有控制终端。
3、禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长,但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
4、关闭打开的文件描述符
进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在地文件系统无法卸下以及无法预料的错误。一般来说,必要的是关闭0、1、2三个文件描述符,即标准输入、标准输出、标准错误。因为我们一般希望守护进程自己有一套信息输出、输入的体系,而不是把所有的东西都发送到终端屏幕上。调用fclose();
5、改变当前工作目录
将当前工作目录更改为根目录。从父进程继承过来的当前工作目录可能在一个装配的文件系统中。因为精灵进程通常在系统再引导之前是一直存在的,所以如果精灵进程的当前工作目录在一个装配文件系统中,那么该文件系统就不能被拆卸。
另外,某些精灵进程可能会把当前工作目录更改到某个指定位置,在此位置做它们的工作。例如,行式打印机假脱机精灵进程常常将其工作目录更改到它们的s p o o l 目录上。
可以调用chdir(“目录”);
6、重设文件创建掩码
将文件方式创建屏蔽字设置为0 。由继承得来的文件方式创建屏蔽字可能会拒绝设置某些许可权。例如,若精灵进程要创建一个组可读、写的文件,而继承的文件方式创建屏蔽字,屏蔽了这两种许可权,则所要求的组可读、写就不能起作用。
7、处理SIGCHLD 信号
处理SIGCHLD信号并不是必需的。但对于某些进程,特别是服务器进程往往在请求到来时生产子进程出来请求。如果父进程不等待子进程结束,子进程将成为僵尸进程,(zombie)而仍占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在系统V下可以简单的将SIGCHLD信号的操作设为SIG-IGN:
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程,这一点与BSD4不同,在BSD4下必须显示等 待子进程结束才能释放僵尸进程。
守护进程实例
守护进程实例包括两部分:主程序test.c和初始化程序init.c。主程序每隔一分钟向/tmp
目录中的日志test.log 报告运行状态。初始化程序中的init_daemon 函数负责生成守护进程
void make_daemon(void)
{
pid_t pid;
FILE * lockfd;
sigset_t sighup;
int i;
extern pid_t getsid(pid_t);
pid = fork();//第一个子进程生成
if (pid < 0) {
printinfo("fork error!",INFOERROR);
exit(FAILEXIT);
}else if (pid > 0) {
printinfo("fork 1 ok! ", INFOSCREEN);
exit(OKEXIT);//退出父进程,摆脱shell的控制
}
pid = getpid();//获得子进程自身的id
lockfd = fopen(PIDFILE, "w");//以下是将pid写入文件
if (lockfd != NULL) {
fprintf(lockfd, "%d\n", pid);
fclose(lockfd);
}//写入pid
if (getsid(0) != pid) {//创建新的会话期
if (setsid() < 0) {
printinfo("backupdaemon setsid error!",INFOERROR);
perror("setsid");
}
}
if(pid=fork()){//再次生成子进程,这时候是孙子进程
exit(0);//退出上一代进程
}else if(pid<0){
exit(1);
}
close(1);//关闭文件
close(2);
chdir(rundir);//改变运行的目录
umask(022);//改变文件权限
}
守护进程的错误输出
守护进程不属于任何终端,所以当需要输出某些信息时,它无法像一般程序那样将信息直接输出到标准输出和标准错误输出中。我们很大时候也不希望每个守护进程将它自己的出错消息写到一个单独的文件中。因为对于系统管理人员而言,要记住哪一个守护进程写到哪一个记录文件中,并定期的检查这些文件,他一定会为此感到头疼的。所以,我们需要有一个集中的守护进程出错记录机制。目前很多系统都引入了syslog记录进程来实现这一目的。
自伯克利开发了BSD syslog并广泛应用以来,BSD syslog 机制被大多数守护进程所使用。我们下面介绍BSD syslog 的用法。有三种方法产生记录消息:
1 内核例程可以调用log函数。任何一个用户进程通过打开和读/dev/klog设备就可以读取这些消息。因为我们无意编写内核中的例程,所以不再进一步说明此函数。
2 大多数用户进程(守护进程)调用syslog函数以产生记录消息。我们将在下面说明其调用序列。这使消息发送至Unix域数据报套接口/dev/log。
3 在此主机上,或通过TCP/IP网络连接到此主机的某一其他主机上的一个用户进程可将记录消息发向UDP端口514。
注意:syslog 函数并不产生这些UDP数据报——它们要求产生此记录消息的进程具有显式的网络编程。
通常,syslog守护进程读取三种格式的记录消息。此守护进程在启动时读一个配置文件。一般来说,其文件名为/etc/syslog.conf,该文件决定了不同种类的消息应送向何处。例如,紧急消息可被送向系统管理员(若已登录),并在控制台上显示,而警告消息则可记录到一个文件中。该机制提供了syslog函数,其调用格式如下
#include
void openlog (char*ident,int option ,int facility);
void syslog(int priority,char*format,……)
void closelog();
调用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,自动调用openlog。调用closelog也是可选择的,它只是关闭被用于与syslog守护进程通信的描述符。调用openlog 使我们可以指定一个ident,以后, 此ident 将被加至每则记录消息中。ident 一般是程序的名称(例如 ,cron ,inetd 等)。option 有4种可能:
LOG_CONS 若日志消息不能通过Unix域数据报发送至syslog,则将该消息写至控制台。
LOG_NDELAY1 立即打开Unix域数据报套接口至syslog守护进程,而不要等到记录第一消息。通常,在记录第一条消息之前,该套接口不打开。
LOG_PERROR 除将日志消息发送给syslog 外,还将它至标准出错。此选项仅由4.3BSDReno及以后版本支持。
LOG_PID 每条消息都包含进程ID。此选项可供对每个请求都fork一个子进程的守护进程使用。
在openlog中设置facility参数的目的是让配置文件可以说明,来自不同设施的消息以不同的方式进行处理。如果不调用openlog,或者以facility 为0来调用它,那么在调用syslog 时,可将facility作为priority参数的一个部分进行说明。调用syslog产生一个记录消息。其priority参数是facility和level的组合,它们可选取的值分别列于下面。level值按优先级从高级到最低按序排列。
发表评论
-
linux中的epoll
2011-06-27 18:34 1715在linux的网络编程中,很长的时间都在使用select来 ... -
time命令
2011-06-08 09:19 925time命令在测试程序效率 ... -
linux 脚本的执行方式
2011-06-03 20:34 26471、source命令用法: source FileNam ... -
linux中单引号、双引号、反引号的作用
2011-06-01 19:53 2307单引号 目的: 为了保护文字不被转换.除了他本身. 就是说除 ... -
linux环境变量和本地变量
2011-06-01 09:03 5238每一种编程语言中, ... -
linux快捷键及任务控制
2011-05-30 21:07 1379Ctrl-C -杀死当前任务 Ctrl-D - 作用是 E ... -
linux 主机名hostname解析
2011-05-29 16:29 35041、 什么是主机名 ... -
解析profile文件
2011-05-25 10:39 1947Linux profile文件的改变会 ... -
su-和su的区别
2011-05-25 10:10 1423joe为普通用户,root为超级用户。 现象如下: [jo ... -
正则表达式
2011-04-21 09:24 802过了上面癿几个简单癿范例,我们可以将基础癿正觃表示法特殊字符汇 ... -
正则表达式
2011-04-21 09:21 860过了上面癿几个简单癿 ... -
ls -l命令详解(转)
2011-04-18 16:18 4608ls -l 列表信息详解 我们平时用ls -l 命令查看一个 ... -
linux的硬连接和软连接
2011-04-18 15:06 9011.Linux链接概念 Linux链接分两种,一种被称为硬链接 ... -
linux 进程管理
2011-04-13 14:00 1056进程是程序的执行过程 存在父进程和子进程 在linux系统中, ... -
linux引导流程
2011-04-13 11:11 940系统引导流程 A 固件firmware(CMOS/BIOS) ... -
X Window
2011-04-11 14:11 822X-Window 是一种协议,而不是一种实现。通过该协议可以实 ... -
linux --ssh
2011-04-05 19:31 1086ssh(secure shell)是一款集远程操作linux和 ... -
网络环境配置
2011-04-05 11:25 871第一中方法: root账号登陆 #setup 出现text ... -
linux--shell
2011-04-05 10:41 1305Shell 简介 shell 是用户和Linux 操作 ... -
linux分区
2011-04-04 17:06 11123 在linux中 每个设 ...
相关推荐
本篇文章提供一个软件实现守护进程的办法,原理就是udp通信,单独写个守护进程程序,专门负责检测主程序是否存在,不存在则启动。主程序只需要启动live类监听端口,收到hello就回复ok就行。 为了使得兼容任意程序,...
《编写Linux守护进程》这篇文献主要探讨了如何在Linux操作系统中创建和管理守护进程,这是一种在后台运行且独立于控制终端的进程,常用于提供系统服务,如HTTP服务器、打印服务等。守护进程的主要特点包括: 1. **...
编写 Linux 守护进程 Linux/Unix 守护进程是指在后台运行的进程,不与控制终端交互,独立于控制终端的输入/输出操作。编写 Linux 守护进程需要了解多个概念,如子进程、进程组、会晤期、信号机制、文件、目录和控制...
C++编写的守护进程,守护进程以windows服务的方式运行,可通过配置文件配置需要守护的exe。
标题中的“守护进程程序C++编写保护进程”指的是在C++编程环境中,通过特定的技术手段创建一个守护进程,它的主要任务是确保指定的C#程序(在这里可能是另一个进程)能够持续运行,即使在某些异常情况下(如用户手动...
Linux下的守护进程编写指南 在 Linux 操作系统中,守护进程(Daemon)是一种特殊类型的进程,它在后台运行,独立于控制终端,用于提供特定的服务或功能。编写 Linux下的守护进程需要使用 C 语言,了解操作系统的...
本篇文章将深入探讨如何用Python编写一个守护进程,以及在进程被杀后自动重启的实现方法。 首先,让我们了解守护进程的基本概念。在Unix-like操作系统中,守护进程通常在用户登录会话之外运行,避免受到用户退出或...
8. **多线程或异步编程**:为了不影响主程序的执行,守护进程的检查和恢复操作可能需要在单独的线程或异步任务中进行。Python的`threading`库或`asyncio`库可以实现这一需求。 通过以上知识点的综合运用,我们可以...
在本场景中,我们讨论的是使用C#编程语言编写的进程守护程序,它专注于一个特定的任务:监控指定的EXE程序,并在需要时重启该程序。 C#是微软开发的一种面向对象的编程语言,它具有丰富的类库和强大的功能,非常...
Linux守护进程是操作系统中的一个重要概念,它是一种在后台运行,独立于任何控制终端,并且通常执行特定服务或任务的进程。...编写守护进程实际上是对普通进程进行改造,使其满足上述守护进程的特性。
下面,我们将深入探讨Delphi编写守护进程的核心概念、实现原理以及压缩包中的文件功能。 首先,Delphi是一种基于Object Pascal的集成开发环境(IDE),它提供了强大的图形化编程工具和丰富的类库,使得开发者能够...
《使用Delphi构建守护进程(服务程序)》 在IT领域,守护进程和服务程序是操作系统中不可或缺的部分,它们常在后台运行,确保关键任务的稳定执行。本文将深入探讨如何利用Delphi编程语言来创建一个守护进程,该进程...
标题“c#实现的守护进程,包含代码”意味着我们将探讨如何使用C#编写一个能够监控并保证某个特定进程始终运行的程序。这种程序可能被设计为Windows服务,以便在操作系统启动时自动运行,并在进程意外终止时重新启动...
项目中使用python写一个监控程序,每隔5秒监控目录,发现文件就...为了谨防程序崩溃,特别编写一个守护进程程序,时刻监控程序是否崩溃并重新启动。 博文: http://blog.csdn.net/alex_bean/article/details/77923178
在Linux环境中,为了确保应用程序如Tomcat能够随系统自动启动并作为守护进程运行,需要进行一系列的配置步骤。本文将详细介绍如何将Tomcat添加到Linux的守护进程,并处理"Invalid user name 'tomcat' specified"的...
守护进程(daemon)是Linux和Unix-like操作系统中的一个重要概念,它们是后台运行的程序,不与任何终端直接关联,主要用于提供...了解如何正确地编写和维护守护进程,不仅可以提高系统的稳定性,还可以提升运维效率。
本文将详细介绍如何编写一个能够每隔10秒创建一个子进程并发送加密消息的守护进程,以及如何确保该守护进程能够接收信号并退出。 #### 守护进程的特点 - **后台运行**:不与任何终端关联,不依赖于用户的交互。 - *...
4. 监控进程状态:为了实现双守护进程,你需要编写代码来监控主守护进程的状态,并在必要时启动备用守护进程。 5. 杀死主进程:当主进程被意外结束时,备用守护进程应该能够检测到这种情况,并开始执行其职责。 6....
1. 超级用户权限:守护进程通常以root权限运行,因此编写时需要特别小心,因为恶意或错误的守护进程可能对系统造成严重破坏。 2. 父进程为init:所有守护进程的父进程号都是1,即init进程,这是系统启动的第一个进程...
然而,这个话题是关于在Windows环境下使用C++编写的一个守护进程实现。 在Windows上,守护进程的实现方式不同于Linux,因为Windows并不直接支持守护进程的概念。在Linux中,守护进程通常通过脱离控制终端、改变工作...