Linux守护进程简单介绍和实例具体解释

Linux守护进程简单介绍和实例具体解释

简单介绍

守护进程(Daemon)是执行在后台的一种特殊进程.它独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种非常实用的进程.Linux的大多数server就是用守护进程实现的.比方,Internetserverinetd,Webserverhttpd等.同一时候,守护进程完毕很多系统任务.比方,作业规划进程crond,打印进程lpd等.

以下是linux系统中常见的一些守护进程.

amd:自己主动安装NFS(网络文件系统)守侯进程
apmd:高级电源管理 
Arpwatch:记录日志并构建一个在LAN接口上看到的以太网地址和IP地址对数据库 
Autofs:自己主动安装管理进程automount,与NFS相关,依赖于NIS 
Bootparamd:引导參数server,为LAN上的无盘工作站提供引导所需的相关信息 
crond:Linux下的计划任务 
Dhcpd:启动一个DHCP(动态IP地址分配)server 
Gated:网关路由守候进程,使用动态的OSPF路由选择协议 
Httpd:WEBserver 
Inetd:支持多种网络服务的核心守候程序 
Innd:Usenet新闻server 
Linuxconf:同意使用本地WEBserver作为用户接口来配置机器 
Lpd:打印server 
Mars-nwe:mars-nwe文件和用于Novell的打印server 
Mcserv:Midnight命令文件server 
named:DNSserver 
netfs:安装NFS、Samba和NetWare网络文件系统 
network:激活已配置网络接口的脚本程序 
nfs:打开NFS服务 
nscd:nscd(Name Switch Cache daemon)server,用于NIS的一个支持服务,它快速缓存用户口令和组成成员关系 
portmap:RPC portmap管理器,与inetd相似,它管理基于RPC服务的连接 
postgresql:一种SQL数据库server 
routed:路由守候进程,使用动态RIP路由选择协议 
rstatd:一个为LAN上的其他机器收集和提供系统信息的守候程序 
ruserd:远程用户定位服务,这是一个基于RPC的服务,它提供关于当前记录到LAN上一个机器日志中的用户信息 
rwalld:激活rpc.rwall服务进程,这是一项基于RPC的服务,同意用户给每一个注冊到LAN机器上的其他终端写消息 
rwhod:激活rwhod服务进程,它支持LAN的rwho和ruptime服务 
sendmail:邮件serversendmail 
smb:Samba文件共享/打印服务 
snmpd:本地简单网络管理候进程 
squid:激活代理serversquid 
syslog:一个让系统引导时起动syslog和klogd系统日志守候进程的脚本 
xfs:X Window字型server,为本地和远程Xserver提供字型集 
xntpd:网络时间server 
ypbind:为NIS(网络信息系统)客户机激活ypbind服务进程 
yppasswdd:NIS口令server 
ypserv:NIS主server 
gpm:管理鼠标 
identd:AUTH服务,在提供用户信息方面与finger相似

守护进程的编程要点

守护进程的编程本身并不复杂,复杂的是各种版本号的Unix的实现机制不尽同样,造成不同Unix环境下守护进程的编程规则并不一致.以下将介绍Linux下守护进程的编程要点并给出具体实例.

不同Unix环境下守护进程的编程规则并不一致.所幸的是守护进程的编程原则事实上都一样,差别在于具体的实现细节不同.这个原则就是要满足守护进程的特性.编程要点例如以下:

  1. 在后台执行.为避免挂起控制终端将Daemon放入后台执行.方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行.
  2. 脱离控制终端,登录会话和进程组.有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID).登录会话能够包括多个进程组.这些进程组共享一个控制终端.这个控制终端一般是创建进程的登录终端.控制终端,登录会话和进程组一般是从父进程继承下来的.我们的目的就是要摆脱它们,使之不受它们的影响.方法是在第1点的基础上,调用setsid()使进程成为会话组长.(说明:当进程是会话组长时setsid()调用失败.但第一点已经保证进程不是会话组长.)setsid() 调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离.因为会话过程对控制终端的独占性,进程同一时候与控制终端脱离.
  3. 禁止进程又一次打开控制终端.如今,进程已经成为无终端的会话组长.但它能够又一次申请打开一个控制终端.能够通过使进程不再成为会话组长来禁止进程又一次打开控制终端.
  4. 关闭打开的文件描写叙述符.进程从创建它的父进程那里继承了打开的文件描写叙述符.如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误.
  5. 改变当前工作文件夹.进程活动时,其工作文件夹所在的文件系统不能卸下.一般须要将工作文件夹改变到根文件夹.对于须要转储核心,写执行日志的进程将工作文件夹改变到特定文件夹如/tmpchdir(“/”).
  6. 重设文件创建掩模.进程从创建它的父进程那里继承了文件创建掩模.它可能改动守护进程所创建的文件的存取位.为防止这一点,将文件创建掩模清除:umask(0).
  7. 处理SIGCHLD信号.处理SIGCHLD信号并非必须的.但对于某些进程,特别是server进程往往在请求到来时生成子进程处理请求.假设父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源.假设父进程等待子进程结束,将添加父进程的负担,影响server进程的并发性能.在Linux下能够简单地将SIGCHLD信号的操作设为SIG_IGN.这样,内核在子进程结束时不会产生僵尸进程.

守护进程实例

守护进程实例包括两部分:主程序test.c和初始化程序init.c.主程序每隔一分钟向/tmp文件夹中的日志test.log报告执行状态.初始化程序中的init_daemon函数负责生成守护进程.读者能够利用init_daemon函数生成自己的守护进程.
1.init.c清单
#include < unistd.h > 
#include < signal.h > 
#include < sys/param.h > 
#include < sys/types.h > 
#include < sys/stat.h > 
void init_daemon(void)  
{  
	int pid;  
	int i;  
	if(pid=fork())  
		exit(0);//是父进程,结束父进程  
	else if(pid< 0)  
		exit(1);//fork失败,退出 
 
	//是第一子进程,后台继续执行  
	setsid();//第一子进程成为新的会话组长和进程组长,并与控制终端分离  
	if(pid=fork())  
		exit(0);//是第一子进程,结束第一子进程  
	else if(pid< 0)  
		exit(1);//fork失败,退出  


	//是第二子进程,继续,第二子进程不再是会话组长  
	for(i=0;i< NOFILE;++i)//关闭打开的文件描写叙述符  
		close(i);  
 
	chdir(“/tmp”);//改变工作文件夹到/tmp  
	
	umask(0);//重设文件创建掩模  
	return;  
} 
2.test.c清单
#include < stdio.h > 
#include < time.h >   
extern void init_daemon(void);//守护进程初始化函数   
main()   
{    
	FILE *fp;     
	time_t t;     
	init_daemon();//初始化为Daemon     
	while(1)//每隔一分钟向test.log报告执行状态     
	{       
		sleep(60);//睡眠一分钟       
		if((fp=fopen(“test.log”,”a”)) >=0)       
		{         
			t=time(0);         
			fprintf(fp,”I’m here at %s\n”,asctime(localtime(&t)) );        
			fclose(fp);       
		}    
	}  
} 

posted @ 2017-05-06 15:48  wzzkaifa  阅读(324)  评论(0编辑  收藏  举报