`
free_bird816
  • 浏览: 206026 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

linux 守护进程 转

阅读更多

守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进程。Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond,打印进程lpd等。
守护进程的编程本身并不复杂,复杂的是各种版本的Unix的实现机制不尽相同,造成不同Unix环境下守护进程的编程规则并不一致。这需要读者注意,照搬某些书上的规则(特别是BSD4.3和低版本的System V)到Linux会出现错误的。下面将全面介绍Linux下守护进程的编程要点并给出详细实例。
一. 守护进程及其特性
守护进程最重要的特性是后台运行。在这一点上DOS下的常驻内存程序TSR与之相似。其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。最后,守护进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端(通常是shell)执行。
总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。如果读者对进程有比较深入的认识就更容易理解和编程了。
二. 守护进程的编程要点
前面讲过,不同Unix环境下守护进程的编程规则并不一致。所幸的是守护进程的编程原则其实都一样,区别在于具体的实现细节不同。这个原则就是要满足守护进程的特性。同时,Linux是基于Syetem V的SVR4并遵循Posix标准,实现起来与BSD4相比更方便。编程要点如下;
1. 在后台运行。
为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。
if(pid=fork())
exit(0);//是父进程,结束父进程,子进程继续
2. 脱离控制终端,登录会话和进程组
有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。
控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:
setsid();
说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
3. 禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:

if(pid=fork())
exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
4. 关闭打开的文件描述符
进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们:
for(i=0;i 关闭打开的文件描述符close(i);>
5. 改变当前工作目录
进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("/")
6. 重设文件创建掩模
进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:umask(0);
7. 处理SIGCHLD信号
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。
三. 守护进程实例
守护进程实例包括两部分:主程序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 >

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,"Im here at %s\n",asctime(localtime(&t)) );
fclose(fp);
}
}
}
以上程序在RedHat Linux6.0下编译通过。步骤如下:
编译:gcc -g -o test init.c test.c
执行:./test
查看进程:ps -ef
从输出可以发现test守护进程的各种特性满足上面的要求

分享到:
评论

相关推荐

    Linux守护进程 Linux守护进程

    Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux守护进程Linux...

    编写Linux守护进程

    编写 Linux 守护进程 Linux/Unix 守护进程是指在后台运行的进程,不与控制终端交互,独立于控制终端的输入/输出操作。编写 Linux 守护进程需要了解多个概念,如子进程、进程组、会晤期、信号机制、文件、目录和控制...

    Linux守护进程的编程方法.pdf

    ### Linux守护进程的编程方法详解 #### 一、守护进程及其特性 守护进程(Daemon)是一种特殊的进程,它运行在后台,独立于控制终端,并且周期性地执行特定任务或等待处理某些事件。Linux系统中许多重要的服务都是...

    linux守护进程源代码

    linux守护进程程序模板带详细注释 守护进程日志 不能被多次运行 详细解释:https://i-beta.cnblogs.com/posts/edit;postId=12095412

    LINUX守护进程介绍

    Linux守护进程是Linux系统中的一种特殊进程,它们在系统启动后独立运行,通常与用户的交互较少,负责执行长期持续的任务,如网络服务、系统监控、定时任务等。这些守护进程在后台持续工作,确保系统的正常运行和服务...

    编写Linux守护进程.pdf

    《编写Linux守护进程》这篇文献主要探讨了如何在Linux操作系统中创建和管理守护进程,这是一种在后台运行且独立于控制终端的进程,常用于提供系统服务,如HTTP服务器、打印服务等。守护进程的主要特点包括: 1. **...

    linux守护进程C实现

    该文档说明在linux下实现守护进程,代码简单易懂,思路清楚。

    Linux系统下守护进程编程方法

    ### Linux系统下守护进程编程方法 #### 一、守护进程概览 守护进程(Daemons)是Linux系统中一类特殊的服务程序,它们通常在后台运行,没有控制终端,也不依赖于任何登录Shell。守护进程的设计目标是高可靠性,...

    Linux系统中守护进程的创建方法.pdf

    "Linux系统中守护进程的创建方法" Linux 系统中守护进程是指在后台运行而又无终端或登录 shell 与之相关联的进程。守护进程可以周期性地执行某种任务或等待处理某些特定的事件,是一种很有用的进程。Linux 的...

    linux守护进程随系统启动而启动

    在Linux系统中,守护进程(daemon)是一种在后台运行且没有控制终端的程序,它们通常用于提供持续的服务,如Web服务器、数据库服务等。要使一个守护进程在系统启动时自动启动,需要将其配置为系统服务,并将其添加到...

    linux守护进程

    总结来说,这个项目可能是在创建一个具有更新功能的Linux守护进程,通过`daemon.c`实现守护进程的转换,`update.c`处理更新逻辑,而`main.c`作为程序的主入口点。头文件提供了函数接口和数据结构的定义,使得不同源...

    基于Linux守护进程的分析与实现.pdf

    守护进程(Daemon)是Linux操作系统中的一个重要组成部分,它们在后台运行,不与用户交互,主要用于提供系统服务。例如,网络服务、时间同步、打印服务等都由守护进程来执行。守护进程能够独立于控制终端运行,并且...

    Linux 守护进程

    ### Linux守护进程(Daemons):编程方法与源码实例解析 #### 一、守护进程的概念与作用 在Linux系统中,守护进程(Daemons)是一类在后台运行且无控制终端的进程,它们通常在系统启动时由init程序启动,并在系统...

    Linux中将Tomcat添加到守护进程

    在Linux环境中,为了确保应用程序如Tomcat能够随系统自动启动并作为守护进程运行,需要进行一系列的配置步骤。本文将详细介绍如何将Tomcat添加到Linux的守护进程,并处理"Invalid user name 'tomcat' specified"的...

    Linux守护进程的研究.pdf

    Linux守护进程,或称为守护程序或精灵进程,是Linux操作系统中的关键组成部分,它们在后台运行,没有控制终端,且通常以超级用户权限运行。守护进程的主要任务是提供系统服务,如网络服务(如HTTP服务器httpd)、...

    xxxx.rar_linux 守护_linux 守护进程

    "xxxx.rar_linux 守护_linux 守护进程"这个压缩包文件可能是提供关于如何创建和管理Linux守护进程的教程或指南。 守护进程的重要性在于它们可以独立于用户会话存在,不受用户登录和注销的影响,确保系统服务的持续...

    Linux守护进程的研究

    ### Linux守护进程的研究 #### 摘要与背景 本文主要探讨了Linux系统下的守护进程(Daemons)的概念、特点及其启动方式,并给出了一个具体的C语言实现案例。守护进程是Linux系统中非常重要的一种进程类型,它运行在...

    linux守护进程加排它锁文件锁

    在linux下实现守护进程并加上排它锁(文件锁),避免重复启动进程

Global site tag (gtag.js) - Google Analytics