linux+守护进程+php,【转载】Linux 守护进程的编程方法

【转载】Linux 守护进程的编程方法

原文见:

http://www.linuxdevelop.org/tingxx/show.php?table=c&id=3

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守护进程的各种特性满足上面的要求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/525859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

翻手算法php,PHP各种常见经典算法总结【排序、查找、翻转等】

本文实例讲述了php各种常见经典算法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;冒泡排序算法public function test() {$arr array(43, 54, 62, 21, 66, 32, 78, 36, 76, 39);var_dump($arr);echo ;$arr $this->bubblesort($arr);var_dump($arr);}public func…

php文件上传详解,PHP文件上传实例详解!!!

这篇文章主要介绍了PHP文件上传实例代码&#xff0c;需要的朋友可以参考下首先来看下上传部分的表单代码&#xff1a;文件&#xff1a; 这里有几个要注意的地方&#xff0c;首先看这句&#xff0c;这里我们采用POST方法&#xff0c;个别浏览器还支持PUT方法&#xff0c;当然这需…

php上传商品信息并显示,第37课 thinkphp5添加商品基本信息及通过前置钩子上传商品主图 模型事件(勾子函数)...

[TOC]手册地址:before_insert(新增之前的操作)要实现的功能上传原图片,在新增数据之前生成三张缩略图片,然后再插入数据添加商品基本信息及通过后置钩子上传商品主图思路控制器里调用模型的save()方法保存数据模型里的用前置勾子beforeInsert()保存之前把上传原图片先成三张缩略…

java下标越界的三种处理方式,数组下标越界,该怎么解决

数组下标越界package import_csv;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.sql.Connect…

commvault备份mysql,备份MySQL数据库的4种方式

备份MySQL数据库的4种方式前言我们试着想一想, 在生产环境中什么最重要&#xff1f;如果我们服务器的硬件坏了可以维修或者换新, 软件问题可以修复或重新安装,但是如果数据没了呢&#xff1f;这可能是最恐怖的事情了吧, 我感觉在生产环境中应该没有什么比数据跟更为重要.那么我…

php $app-run(),Thinkphp 5.x 应用启动 App::run()

在上文加载完配置等一系列工作之后&#xff0c;进入App::run()&#xff0c;在run()方法中&#xff0c;首先通过自动加载机制拿到 Request 的一个实例接着 $config self::initCommon()初始化公共配置&#xff0c;先是 addNamespace 添加app当前所在的命名空间&#xff0c;然后 …

php react-native,React-Native+Mobx实现商城APP

这次给大家带来React-NativeMobx实现商城APP&#xff0c;React-NativeMobx实现商城APP的注意事项有哪些&#xff0c;下面就是实战案例&#xff0c;一起来看一下。最近一直在学习微信小程序&#xff0c;在学习过程中&#xff0c;看到了 wxapp-mall这个微信小程序的项目&#xff…

mysql 流程控制语句,mysql PL(procedure language)流程控制语句

在MySQL中&#xff0c;常见的过程式SQL语句可以用在存储体中。其中包括IF语句、CASE语句、LOOP语句、WHILE语句、ITERATE语句和LEAVE语句&#xff0c;它们可以进行流程控制。IF语句相当于Java中的if()...else if()...else...CASE语句相当于Java中的switch()...case A:...break;…

mysql 空闲几分钟速度变慢,MYSQL 运作一小段时间后,速度变得奇慢。而CPU基本空闲状态...

当前位置:我的异常网 MySQL MYSQL 运作一小段时间后&#xff0c;速度变得奇慢。而CPU基本MYSQL 运作一小段时间后&#xff0c;速度变得奇慢。而CPU基本空闲状态www.myexceptions.net 网友分享于&#xff1a;2015-08-26 浏览&#xff1a;11次MYSQL 运行一小段时间后&#xff…

matlab axis 用法,MATLAB中regionprops的用法

Matlab图像处理函数&#xff1a;regionprops这里给出在Matlab图像处理工具箱中非常重要的一个图像分析函数&#xff1a;regionprops。顾名思义&#xff1a;它的用途是get the properties of region&#xff0c;即用来度量图像区域属性的函数。语法STATS regionprops(L,propert…

emqx配置mysql认证,emqx使用mysql完成用户密码验证和ACL鉴权

emqx使用mysql完成用户密码验证和ACL鉴权emqx使用mysql完成用户密码验证和ACL鉴权摘要&#xff1a;前几篇博客介绍的是使用配置文件配置了ACL和客户端用户名密码配置实现生产环境下的安全登录和权限控制&#xff0c;各项配置比较繁琐&#xff0c;修改起来比较麻烦&#xff0c;下…

MATLAB课程表分配问题,求助matlab大神,学校的课程安排太骚了,我们压根就不用学matlab...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼上了MATLAB&#xff0c;可是对数学完全不感兴趣。老师弄了个作业&#xff0c;代码附件了。求大佬帮忙理解原理后简单做一个不一样的过程的程序。帮忙注释一下代码。(一开始忘记下载要币了。不好意思)两个.m文件&#xff0c;需要放一…

php时间转分钟前,PHP把时间转换成几分钟前几小时前几天前

现在很多网站将时间的显示都变得比较人性化&#xff0c;今天项目有一个也需要在对应的资讯后面显示为几分钟前、几小时前&#xff0c;接下来吾爱编程为大家分享一下PHP把时间转换成几分钟前、几小时前几天前的方法&#xff0c;有需要的小伙伴可以参考一下&#xff1a;1、项目需…

emlog_toolkit.php,emlog 4.0版本IIS6下伪静态划定规矩

emlog默许不能生成静态文件&#xff0c;不过彷佛有生成静态页面的相干插件&#xff0c;该插件博客吧先不研讨&#xff0c;本日博客簿要引见的是emlog 4.0版本在IIS6环境下的伪静态划定规矩&#xff0c;人人都晓得&#xff0c;经由过程伪静态能够让博客文章网址变得对搜索引擎越…

php如何封装数组,PHP数组转对象 对象转数组封装类

代码如下/*** 数组 转 对象** param array $arr 数组* return object*/function array_to_object($arr) {if (gettype($arr) ! array) {return;}foreach ($arr as $k > $v) {if (gettype($v) array || getType($v) object) {$arr[$k] (object)array_to_object($v);}}retu…

api.php phpcms,phpcms程序api怎么写接口

易站通&#xff0c;带你玩转PHPCMS建站程序&#xff0c;让你更快的熟悉该程序下面让我们来学习吧phpcms api怎么写接口&#xff1f;最近自己开发了一套crm系统&#xff0c;想着如果将来能卖出去&#xff0c;能不能再界面动态调用自己网站的推荐信息&#xff0c;算是一种广告吧&…

oracle修改窗口字体大小,jQuery之字体大小的设置方法

先获取字体大小&#xff0c;进行处理。再将修改的值保存。slice() 方法可从已有的数组中返回选定的元素。arrayObject.slice(start,end)。start 必需。规定从何处开始选取。如果是负数&#xff0c;那么它规定从数组尾部开始算起的位置。也就是说&#xff0c;-1 指最后一个元素&…

oracle 删除表 索引也会删除吗,Oracle 删除当前用户下所有的表、索引、序列

通过下面语句可以得到要删除Oracle的所有表、索引、序列... 的语句select drop table || table_name ||;||chr(13)||chr(10) from user_tables; --delete tablesselect drop view || view_name||;||chr(13)||chr(10) from user_views; --delete viewsselect drop sequence …

基于Java、Kafka、ElasticSearch的搜索框架的设计与实现

Jkes是一个基于Java、Kafka、ElasticSearch的搜索框架。Jkes提供了注解驱动的JPA风格的对象/文档映射&#xff0c;使用rest api用于文档搜索。项目主页&#xff1a;https://github.com/chaokunyang/jkes安装可以参考jkes-integration-test项目快速掌握jkes框架的使用方法。jkes…

Docker是传统的应用发布管理的终结者么?

译者注&#xff1a;使用Docker能真正改善传统的应用发布管理中遇到的问题么&#xff1f;以下是译文&#xff1a;自从2013年发布以来&#xff0c;Docker已经成为每一个操作管理者眼中的最爱。如果你一直与世隔绝&#xff0c;这里恰恰是你错过的部分。Docker是在一个操作环境地址…