Linux多任务编程之七:Linux守护进程及其基础实验(转)

来源:CSDN  作者:王文松  转自Linux公社

------------------------------------------------------------------------------------------------

守护进程概述

守护进程,又叫daemon进程(不知怎的,我突然想起来吸血鬼日记中的达蒙了,很好看的美剧),是Linux中的后台服务进程。 他是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或者等待处理某些发生的事件。守护进程常常在系统引导载入时启动,在系统关闭时终 止。Linux有很多系统哦服务,大多数服务都是通过守护进程实现的。同时,守护进程还能完成许多系统任务,例如,作业规划进程cronf、打印进程 lqd等(这里的结尾字母 d 就是 daemon的意思)。

在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端, 当控制终端关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到接收到某种信号或者整个系统关闭时才退出。如果想 让某个进程不因为用户、终端或者其它的变化而受到影响,那么就必须把这个进程变成一个守护进程。可见,守护进程是非常重要的。

编写守护进程步骤

编写守护进程遵循一个特定的流程,下面就说一下守护进程的创建步骤。

1、创建子进程,父进程退出。

这是编写守护进程的第一步。由于守护进程是脱离控制终端的,因此,完成第一步后就会在shell终端造成一种程序已经运行完毕的假象,之后的所有工作都在子进程中完成,而用户在shell终端则可以执行其他的命令,从而在形式上做到与控制终端的脱离。

但是,父进程创建了子进程后退出,此时该子进程不就没有父进程了吗?守护进程中确实会出现这么一个有趣的现象:由于父进程已经先于子进程退出,就会 造成子进程没有父进程,从而变成一个孤儿进程。在Linux中,每当系统发现一个孤儿进程时,就会自动由1号进程(也就是 init 进程)收养它,这样原先的子进程就会变成 init 进程的子进程。其关键代码如下;

2、在子进程中创建新会话

这个步骤是创建守护进程最重要的一步,虽然实现非常简单,但意义却非常重大。在这里使用的是系统函数 setsid(),在具体介绍 setsid()之前,先了解以下两个概念:进程组和会话期。

● 进程组。进程组是一个或多个进程的集合。进程组由进程组ID来唯一标识。除了进程号PID之外,进程组ID也是一个进程的必备属性。每隔进程组都有一个组 长进程,其组长进程的进程号PID等于进程组ID,且该进程组ID不会因为组长进程的退出而受到影响。(组长没了,再找个组员来担任组长呗)

● 会话期。会话组是一个或多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。进程组和会话期之间的关系如图1所示:

接下来具体介绍 setsid()的相关内容。

① setsid()函数的作用。setsid()函数用于创建一个新的会话组,并让执行此函数的进程担任该会话组的组长。调用setsid()有以下3个作用:

● 让进程摆脱原会话的控制

● 让进程摆脱原进程组的控制

● 让进程摆脱原控制终端的控制

那么,回过头来想想,在创建守护进程时为什么要调用 setsid()函数呢?是这样的,在创建守护进程的第一步中,调用了fork()函数创建子进程再令父进程退出。由于在调用 fork()函数时,子进程全盘复制了父进程的会话期、进程组和控制终端等,虽然父进程退出了,但原先的会话期、进程组和控制终端等并没有改变,因此,还 不是真正意义上的独立。而setsid()函数能够使进程完全独立出来,从而脱离所有其他进程的控制。

② setsid函数格式

3、改变当前目录为根目录

这一步也是必要的步骤。使用fork()创建的子进程继承了父进程的当前工作目录。由于在进程运行过程中,当前目录所在的文件系统(如“/mnt /usb”等)是不能卸载的,这对以后的使用会造成诸多的麻烦(如系统由于某种原因需要进入单用户模式)。因此,通常的做法是让“/”作为守护进程的当前 工作目录,这样就可以避免上述问题。当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数是chdir()。

4、重设文件权限掩码

文件权限掩码是指屏蔽掉文件权限中的对应位。例如,有一个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork() 函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活 性。设置文件权限掩码的函数是umask()。通常的使用方法为umask(0)。

5、关闭文件描述符

同文件权限掩码一样,用fork()函数新建的子进程会从父进程那里继承一些已经打开的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法被卸载。

事实上,在上面的第2步之后,守护进程已经与所属的控制终端失去了联系,因此,从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如 printf())输出的字符也不可能在终端上显示出来。所以文件描述符为0,1和2的3个文件(常说的输入/输出和报错这3个文件)已经失去了存在的价 值,也应该被关闭。通常了,按如下方式关闭文件描述符:

有关getdtables()的作用请看博客:

到这里,一个简单的守护进程就建立起来了。创建守护进程的流程图如图所示:

基础实验

本实验按照以上的创建流程建立了一个守护进程,然后让守护进程每隔10s向日志文件/home/song/tmp/daemon.log 写入一句话。程序代码如下,我也上传到网站,点此下载

我们先看一下 /tmp文件夹下是没有daemon.log的

下载文件后,使用命令编译:gcc dameon.c -o daemon

然后执行命令: ./daemon 你可以看到此时没有看到有什么变化

使用命令:ps -ef|grep ./daemon 利用ps中的关键字来查看系统当前正在运行的进程中,有没有咱们的daemon进程

可以看到咱们的守护进程已经在运行了,再来看看/tmp目录下的内容

可以看到,已经有daemon.log日志文件了。

然后使用命令:tail -f /tmp/daemonl.log ,可以看到该程序每隔10s就会在对应的文件中输入相关的内容

到这里,这个实验就已经结束了,通过前边使用命令:ps -ef|grep ./daemon可以看到咱们这个进程的进程号是3346,现在使用命令:kill -9 3346将这个进程杀死,同时也把/tmp中的daemon.log文件页删除,方便咱们下边的实验。

守护进程的出错处理

在编写守护进程的具体调试过程中会发现,由于守护进程完全脱离了控制终端,因此,不能像其他普通进程一样,将错误信息输出到控制终端来通知程序员, 即使使用gdb也无法正常调试。那么,守护进程的进程要如何调试呢?一种通用的方法是使用 syslog 服务,将程序中的出错信息输入到系统日志文件中(如“/var/log/messages”),从而可以直观地看到程序的问题所在(“/var/log /message”系统日志文件只能由拥有root权限的超级用户查看。在不同的Linux发行版本中,系统日志文件路径全名可能有所不同,例如,我的Ubuntu中路径就是“/var/log/syslog”)。

syslog 是Linux中的系统日志管理服务,通过守护进程 syslogd 来维护。该守护进程在启动时会读一个配置文件“/etc/syslog.conf”,该文件决定了不同种类的消息会发送到何处。例如,紧急消息可被送到系 统管理员并在控制台上显示,而警告消息则可被记录到一个文件中。

该机制提供了3个syslog相关函数,分别为 openlog()、syslog()和closelog(),下面就分别介绍这3个函数。

函数说明

openlog()函数用于打开系统日志服务的一个链接;syslog()函数用于向日志文件中写入信息,在这里可以设定消息的优先级、消息输出格式等;closelog()函数用于关闭系统日志服务的链接。

函数格式

基础实验

咱们可以尝试用普通身份执行程序(RedHat中不要用root,ubuntu正常运行就可以)。由于这里的open()函数必须具有root权限,因此,syslog 会将错误信息写入到系统日志文件("如/var/log/syslog")中,结果如下图

本实验文件syslog_damen.c下载

免费下载地址在 http://linux.linuxidc.com/

用户名与密码都是www.linuxidc.com

具体下载目录在 /2013年资料/6月/12日/Linux多任务编程

时间: 2024-10-27 02:36:48

Linux多任务编程之七:Linux守护进程及其基础实验(转)的相关文章

Linux多任务编程之四:exit()函数及其基础实验(转)

来源:CSDN  作者:王文松   转自Linux公社 exit()和_exit()函数 函数说明 创建进程使用fork()函数,执行进程使用exec函数族,终止进程则使用exit()和_exit()函数.当进程执行到exit()或 _exit()函数时,进程会无条件的停止剩下的所有操作,清除各种数据结构,并终止本进程的运行.但是,这两个函数还是有区别的,其调用过程如图1所 示: 从图1可以看出,_exit()函数的作用是:直接使进程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据结构

Linux多任务编程之三:exec函数族及其基础实验(转)

来源:CSDN  作者:王文松  转自:Linux公社 exec函数族 函数族说明 fork() 函数用于创建一个新的子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的子进程如何执行呢?exec 函数族就提供了一个在进程中启动另一个程序执行的方法.它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段.代码段和堆栈 段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了.另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执 行

嵌入式 Linux进程间通信(三)——守护进程

嵌入式 Linux进程间通信(三)--守护进程 一.守护进程简介 1.守护进程简介 守护进程(Daemon)是运行在后台.独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件的一种特殊进程.守护进程常常在系统引导装入时启动,在系统关闭时终止.Linux的大多数服务器就是用守护进程实现的.比如,Internet服务器inetd,Web服务器httpd等.同时,守护进程完成许多系统任务.比如,作业规划进程crond等.守护进程的创建本身并不复杂,复杂的是各种版本的Unix的实现机制不尽相同

Linux多任务编程之五:exit()和_exit()函数(转)

来源:CSDN  作者:王文松   转自:Linux公社 ------------------------------------------------------------------------------------------------------------------------------------------------ wait()和waitpid() 函数说明 wait()函数用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接收到了一个指

ASP.NET Core Linux下为 dotnet 创建守护进程(必备知识)

原文:ASP.NET Core Linux下为 dotnet 创建守护进程(必备知识) 前言 在上篇文章中介绍了如何在 Docker 容器中部署我们的 asp.net core 应用程序,本篇主要是怎么样为我们在 Linux 或者 macOs 中部署的 dotnet 程序创建一个守护进程,来保证我们的程序在异常或者是电脑重启的时候仍然能够正常访问. 如果你以后用准备使用 asp.net core来开发项目的话,程序并且部署到 Linux 上的话,那么此篇文章你值得收藏. 如果你觉得对你有帮助的话

Windows 和 Linux 上Redis的安装守护进程配置

# Windows 和 Linux 上Redis的安装守护进程配置 Redis 简介 ? Redis是目前最常用的非关系型数据库(NOSql)之一,常以Key-Value的形式存储.Redis读写速度远远比关系型数据库高(mysql.oracle).所以常用作项目热数据缓存 Windows上的安装配置 1) 在GitHub下载https://github.com/microsoftarchive/redis/releases 2) 解压并安装redis服务以支持守护进程(后台启动) 解压之后目录

Linux多线程编程和Linux 2.6下的NPTL

Linux多线程编程和Linux 2.6下的NPTL 在Linux 上,从内核角度而言,基本没有什么线程和进程的区别--大家都是进程.一个进程的多个线程只是多个特殊的进程他们虽然有各自的进程描述结构,却共享了同一 个代码上下文.在Linux上,这样的进程称为轻量级进程Light weight process.致此,就是关于线程的总体概念了,我们往往就在了解这个概念的情况下开始我们的多线程编程之旅.这对于多线程编程入门已经足够了,然而事 实上线程却要复杂的多. 首先多线程间的优先级调度,内存资源(

Linux编程之《守护进程》

Intro ----- 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装入时启动,在系统关闭时终止.Linux系统有很多守护进程,大多数服务都是通过守护进程实现的,同时,守护进程还能完成许多系统任务,例如,作业规划进程crond.打印进程lqd等(这里的结尾字母d就是Daemon的意思). 由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个

Linux多任务编程之一:任务、进程、线程(转)

来源:CSDN  作者:王文松  转自:Linux公社 Linux下多任务介绍 首先,先简单的介绍一下什么叫多任务系统?任务.进程.线程分别是什么?它们之间的区别是什么?,从而可以宏观的了解一下这三者,然后再针对每一个仔细的讲解. 什么叫多任务系统?多任务系统指可以同一时间内运行多个应用程序,每个应用程序被称作一个任务. 任务定义:任务是一个逻辑概念,指由一个软件完成的任务,或者是一系列共同达到某一目的的操作. 进程定义:进程是指一个具有独立功能的程序在某个数据集上的一次动态执行过程,它是系统进