欢迎来到天天文库
浏览记录
ID:35983874
大小:40.50 KB
页数:4页
时间:2019-04-29
《unix系统开发-守护进程》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、UNIX系统开发-守护进程守护进程(Demons)是在后台运行而有无终端或者登录shell和它结合在一起的进程。有许多标准的守护进程,其中的一些周期地运行来完成特定的任务(像atrun,典型地由cron每五分钟执行一次),而其余的则连续地运行,等待处理某些特定的事件(像inetd和lpd)。1.原理有几种启动守护进程的方法。最常用的是:在引导系统时启动。在这时运行的守护进程通常在系统启动script的执行周期间被启动。这些script典型地被存放在目录/etc/rc.d中。手工地,从shell提示符启动.对任何具有相应的执
2、行权限的用户可以用这种方法启动守护进程由crond守护进程启动。这个程序查询通常存放在/var/spool/crontabs目录中的一组文件,它们规定了要执行的周期性任务由执行at命令启动。这将使一个程序在规定的日期和时间执行一次。为了做到完全稳定可靠,一个守护进程应该能够在所有的这些方式下被正确地执行。唯一问题是其中的一些启动方法使守护进程处于一种脆弱状态。它可能受到在它运行之前为它设置的环境的影响。你将要写的将普通程序转换成守护程序的大部分代码将涉及到把你的程序与这些环境影响隔离开。除此之外,准备作为守护进程使用的程序
3、通常必须比普通的用户程序更可靠。你常常需要这样去编写程序,使得当它作为守护程序运行时,即使出现各种类型的系统错误,也不至于引起程序的崩溃。2.实践在启动守护进程的过程中,包含了比你能想象的更多的步骤,虽然它们全部可能只用极少的代码去完成。本节的其余部分将逐步介绍这一过程的更重要的方面。2.1关闭文件描述符第一项任务是关闭所有不必要的文件描述符。如果你的守护进程留下一个普通文件处于打开状态,这将阻止该文件被任何其他进程从文件系统中删除。它也阻止包含该打开文件的已装配的文件系统被卸下。在终端文件(通常是stdin,stdout
4、和stderr)的情况下,关闭不必要的连接更加重要。因为当在该终端上的用户退出系统后,将执行vhangup()系统调用,守护进程访问该终端的权利将被撤消。这表示守护进程虽然由它认为处于打开状态的文件描述符,事实上它已不再能通过这些文件描述符访问该终端。最简单的做法是关闭所有的文件描述符,它将使守护进程和这些问题隔离开。将close()系统调用用在没有打开的文件描述符上不存在任何问题,所以下列的代码段可以被使用:#includefor(id=1;i5、FILE给出一个进程一次可以打开的文件的最大个数。2.2甩开控制终端如果一个进程是从登录对话过程中被启动,而它将从对话过程中继承与它结合的控制终端。对于守护进程来说,其结果是它可以接收由该控制终端产生的信号(诸如SIGINT和SIGQUIT),如果这些信号不被捕获,将结束该进程。这个问题可以由守护进程忽略所有它可能忽略的信号而加以克服,但是这将阻止守护进程利用信号作为简单的进程间通信手段使用。一个较好的解决方式是使用守护进程本身和控制终端分开,使得这些信号首先不传播到守护进程。在linux下这样做的一种方法是打开文件/de6、v/tty,并且使用ioctl()在该文件上执行TIOCNOTTY命令。它使得每一个具有控制终端的进程通过文件/dev/tty访问那个终端。简短的代码如下:if((fd=open("/dev/tty",D_RDWR))>=0){ioctr(fd,TIOCNOTTY,0);close(fd);}在LIUNX下,这不是使进程本身和它的控制终端分离的唯一的方法。事实上,在下一节中我们将看到做这件事的更简单的方法。2.3脱离对话过程和进程组进程从它的双亲进程获得它的对话过程和进程组识别号。由于它属于一个对话过程和一个进程组,一个进7、程将接收到任何作为整体发送给该对话过程或进程组的信号。这类似于从控制终端接收信号的问题,并且实际的解决方法也是同样的,即将进程和这一环境影响分开。在POSIX中存在一个单一的系统调用,它将进程和它的当前的对话过程和进程组分离开,并且把它设置为一个新的对话过程的领头进程(leader)。这个系统调用设置对话过程识别号:setsid()由于一个控制终端仅可以和单一的对话过程相联,作为setsid()调用的副作用,它也把进程和它的控制终端(如果它有控制终端的话)分离开。setsid()的唯一问题是:只有执行它的守护进程不是对话过8、程的领头进程(leader)时,它才能发挥作用。在我们的情况下,容易假定该守护进程不是对话过程的领头进程,但是这不能保证,除非采取特殊步骤使它成为这样。你可以毫无疑问地这样说:如果一个特定的对话过程的领头进程执行了fork()系统调用,则默认地这一子女进程应该不是对话过程的领头进程。这提供了确保执行se
5、FILE给出一个进程一次可以打开的文件的最大个数。2.2甩开控制终端如果一个进程是从登录对话过程中被启动,而它将从对话过程中继承与它结合的控制终端。对于守护进程来说,其结果是它可以接收由该控制终端产生的信号(诸如SIGINT和SIGQUIT),如果这些信号不被捕获,将结束该进程。这个问题可以由守护进程忽略所有它可能忽略的信号而加以克服,但是这将阻止守护进程利用信号作为简单的进程间通信手段使用。一个较好的解决方式是使用守护进程本身和控制终端分开,使得这些信号首先不传播到守护进程。在linux下这样做的一种方法是打开文件/de
6、v/tty,并且使用ioctl()在该文件上执行TIOCNOTTY命令。它使得每一个具有控制终端的进程通过文件/dev/tty访问那个终端。简短的代码如下:if((fd=open("/dev/tty",D_RDWR))>=0){ioctr(fd,TIOCNOTTY,0);close(fd);}在LIUNX下,这不是使进程本身和它的控制终端分离的唯一的方法。事实上,在下一节中我们将看到做这件事的更简单的方法。2.3脱离对话过程和进程组进程从它的双亲进程获得它的对话过程和进程组识别号。由于它属于一个对话过程和一个进程组,一个进
7、程将接收到任何作为整体发送给该对话过程或进程组的信号。这类似于从控制终端接收信号的问题,并且实际的解决方法也是同样的,即将进程和这一环境影响分开。在POSIX中存在一个单一的系统调用,它将进程和它的当前的对话过程和进程组分离开,并且把它设置为一个新的对话过程的领头进程(leader)。这个系统调用设置对话过程识别号:setsid()由于一个控制终端仅可以和单一的对话过程相联,作为setsid()调用的副作用,它也把进程和它的控制终端(如果它有控制终端的话)分离开。setsid()的唯一问题是:只有执行它的守护进程不是对话过
8、程的领头进程(leader)时,它才能发挥作用。在我们的情况下,容易假定该守护进程不是对话过程的领头进程,但是这不能保证,除非采取特殊步骤使它成为这样。你可以毫无疑问地这样说:如果一个特定的对话过程的领头进程执行了fork()系统调用,则默认地这一子女进程应该不是对话过程的领头进程。这提供了确保执行se
此文档下载收益归作者所有