`
wangyihust
  • 浏览: 436575 次
文章分类
社区版块
存档分类
最新评论

Linux 守护进程的编程方法

阅读更多
--  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,"I\'m 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系统下守护进程编程方法 #### 一、守护进程概览 守护进程(Daemons)是Linux系统中一类特殊的服务程序,它们通常在后台运行,没有控制终端,也不依赖于任何登录Shell。守护进程的设计目标是高可靠性,...

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

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

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

    "Linux系统下守护进程编程方法" 守护进程(Daemon)是一种特殊的后台进程,它没有控制终端,也不与用户交互。守护进程通常用于提供一些服务,例如网络服务、数据库服务等。Linux系统下守护进程编程方法是指在Linux...

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

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

    【ASP.NET编程知识】.net Core 3.0 WebApi 创建Linux守护进程的方法.docx

    .NET Core 3.0 WebApi 创建 Linux 守护进程的方法 在 Linux 服务器上,直接使用 dotnet &lt;app_assembly.dll&gt; 命令来运行 .NET Core WebApi 应用程序可能会导致应用程序不稳定,关闭终端窗口后应用程序也会停止运行。...

    一种LINUX操作系统守护进程的编程实现方法.pdf

    "Linux操作系统守护进程编程实现方法" 本文主要介绍了Linux操作系统下的守护进程编程实现方法。守护进程是一种特殊的进程,在后台运行,独立于控制终端,并周期性地执行某种任务或等待处理某些发生的事件。Linux...

    Linux系统下守护进程编程方法 (1).pdf

    Linux系统下守护进程编程方法 (1).pdf

    编写Linux守护进程.pdf

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

    Linux 守护进程

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

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

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

    Linux操作系统下守护进程的编程方法

    ### Linux操作系统下守护进程的编程方法 #### 一、守护进程及其特性 守护进程(Daemon)是一种特殊类型的进程,它在后台运行,并且通常没有控制终端。守护进程的主要任务是执行周期性的操作或者响应特定的事件。...

    linux守护进程

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

    Linux守护进程的研究

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

    Linux特殊进程之守护进程测试代码

    Linux系统编程——特殊进程之守护进程,相关教程链接如下: http://blog.csdn.net/tennysonsky/article/details/45970087

    Delphi写的守护进程(服务程序)

    守护进程(Daemon)通常是指在后台运行且不与终端交互的进程,它在Linux环境中常见。而在Windows中,我们称之为服务。Delphi提供了一种简便的方式来创建服务程序,这主要得益于它的VCL库中的TService组件。 在描述...

    Linux进程编程技术.doc

    Linux 进程编程技术 Linux 进程编程技术是指在 Linux 操作系统中,程序员可以使用各种技术来创建、管理和控制进程的执行。以下是 Linux 进程编程技术的相关知识点: 1. 进程的基本概念及结构 在 Linux 中,进程是...

    Linux守护进程的编写.pdf

    Linux守护进程是操作系统中的一个重要概念,它是一种在后台运行,独立于任何控制终端,并且通常执行特定服务或任务的进程。守护进程在Linux系统中扮演着服务器的角色,例如inetd、httpd等,用于提供网络服务,还有像...

    c++ linux 守护进程

    在Linux系统中,守护进程(Daemon)是一种在后台运行且没有控制终端的进程。它们通常是系统启动时自动启动,用于提供服务或者执行特定任务。...理解并掌握守护进程的原理和创建方法对于任何系统级编程都是至关重要的。

    socket_daemon.rar_daemon_linux 守护进程_socket daemon._守护进程_服务 守护

    在IT行业中,守护进程...总的来说,通过`serverd.c`和`client1.c`这两个示例,我们可以深入理解Linux守护进程的创建和Socket通信的基本原理,这对于理解网络服务的底层运作和开发自己的服务程序是非常有价值的。

Global site tag (gtag.js) - Google Analytics