Chinaunix首页 | 论坛 | 博客
  • 博客访问: 912449
  • 博文数量: 299
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2493
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-21 10:07
个人简介

Linux后台服务器编程。

文章分类

全部博文(299)

文章存档

2015年(2)

2014年(297)

分类: LINUX

2014-07-09 16:52:25

【守护进程介绍】
Linux系统启动时往往要启动很多的系统服务程序,比如apache,ftp,telnet等。这些系统服务程序往往运行在后台,没有控制终端,在系统引导装入时启动,在系统关闭时终止,周期性的执行某项任务或者等待处理某项任务。这样的进程叫守护进程或者精灵进程。
 
编写守护进程一般是在普通进程基础上,根据守护进程的特点进行改造。编程实现守护进程要遵循的几个要点:
 
1.父进程是init进程,后台执行
用fork函数创建子进程,并将父进程终止,这样子进程成为孤儿进程被init进程收养,并在后台执行。
 
2.脱离控制终端,创建新的会话和进程组,并成为首进程
进程组是一个或者多个进程的集合,进程组有对应的组ID,是由领头进程的进程号决定的;会话是一个或者多个进程组的集合,每个会话也有一个领头进程。每个进程属于一个进程组,每个进程组又属于一个会话。当用户从终端登陆系统时,系统会创建一个会话,该终端上启动的进程都会被系统规划到会话的进程组中。会话中的进程是通过会话的领头进程与一个控制终端相连。
 
由于守护进程没有控制终端,而通过fork创建的子进程继承了父进程的控制终端、进程组和会话,因此必须重新创建会话,以脱离父进程的影响。
pid_t setsid(void);  //返回调用进程的会话ID
前提:调用setsid的进程不能为一个进程组的领头进程,fork的子进程一定满足
结果:创建新的会话,调用setsid的子进程成为会话中唯一进程组,组ID=调用进程的ID.
 
3.更改当前工作目录
fork的子进程继承父进程的工作目录,但是如果作为守护进程使用,进程没有结束之前,工作目录不能被卸载。所以一般将工作目录使用chdir()更改到根目录下。
 
4.关闭文件描述符,重定向标准输入、输出、错误
需要关闭从父进程继承来的无需使用的文件描述符。运行在后台,不需要在终端有任何输出信息。
 
5.重设权限
屏蔽其他用户对守护进程创建的临时文件的访问权限。
 
【代码实现】
#include
#include
#include
#include
#include
#include
void daemon_def(void)
{
 pid_t pid;
 int fd;
 pid = fork();
 if(pid<0)
 {
  perror("Fail to creat child process.\n");
  return;
 }
 else if(pid>0)
 {
  exit(0);
 }
 else
 {
  pid = setsid();
  if(pid<0)
  {
   perror("Setsid failed.\n");
   return;
  }
  chdir("/");
  if((fd = open("/dev/null",O_RDWR,0))==-1)
  {
   perror("Can't open dev file.\n");
   return;
  }
  dup2(fd,STDIN_FILENO);
  dup2(fd,STDOUT_FILENO);
  dup2(fd,STDERR_FILENO);
  umask(0027);
  return;   //这里错用成exit,子进程直接终止了,即main没有执行到sleep就结束了。ps看不到。  
 }
}
 
int main(void)
{
 daemon_def();
 sleep(1000);
 return 0;
}
 
【执行结果】
 gcc -o damm syslog.c
 ./damm
 ps -ef | grep damm
gaolu     5381     1  0 22:23 ?        00:00:00 ./damm  //生成进程:父进程PID=1,TTY=?没有控制终端
gaolu     5396  5353  0 22:23 pts/0    00:00:00 grep damm

阅读(1412) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~