什么是守护进程?

一个守护进程通常补认为是一个不对终端进行控制的后台任务。它有三个很显著的特征:在后台运行,与启动他的进程脱离,无须控制终端。常用的实现方式是fork() -> setsid() -> fork()

在glibc里有一个函数daemon。调用此函数,就可使当前进程脱离终端变成一个守护进程,具体内容参见man daemon。PHP中暂时没有此函数,PHP程序实现守护进程化有2种方法:

使用系统命令nohup

nohup php myprog.php > log.txt &

&,这样执行程序虽然也是转为后台运行,但实际上是依赖终端的,当用户退出终端时进程就会被杀掉。需要使用nohup来实现

PHP脚本函数实现:

<?php
function daemon()
{
$pid = pcntl_fork();
if($pid < 0){
die("fork(1) failed!\n");
}elseif($pid > 0){
exit; //让终端启动的进程退出
}
chdir("/"); //改变当前目录为根目录
umask(0); //重设文件权限掩码
//建立一个有别于终端的新session以脱离终端
$sid = posix_setsid();
if (!$sid) {
die("setsid failed!\n");
}
$pid = pcntl_fork();
if($pid < 0){
die("fork(1) failed!\n");
}elseif($pid > 0){
exit; //父进程退出, 剩下子进程成为最终的独立进程
}
//关闭标准I/O流
if (defined('STDIN')) {
fclose(STDIN);
}
if (defined('STDOUT')){
fclose(STDOUT);
}
if (defined('STDERR')) {
fclose(STDERR);
}
}
daemon();
sleep(1000);

这里较为关键的二个php函数是pcntl_fork()和posix_setsid()

  • fork()一个进程,则表示创建了一个运行进程的副本,副本被认为是子进程,而原始进程被认为是父进程。当fork()运行之后,则可以脱离启动他的进程与终端控制等,也意味着父进程可以自由退出。
  • setsid(),它首先使新进程成为一个新会话的“领导者”,最后使该进程不再控制终端,这也是成为守护进程最关键的一步,这意味着,不会随着终端关闭而强制退出进程。对于一个不会被中断的常驻进程来说,这是很关键的一步。
  • 进行最后一次fork(),这一步不是必须的,但通常都这么做,它最大的意义是防止获得控制终端。(在直接打开一个终端设备,而且没有使用O_NOCTTY标志的情况下, 会获得控制终端)

其它事项说明:

  • chdir() 守护进程默认继承了父进程的当前工作目录,当系统磁盘发生umount时将造成诸多的麻烦,通常将”/” 作为守护进程的当前工作目录,可以避免上述的问题
  • umask() 守护进程默认继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性
  • fclose(STDIN), fclose(STDOUT), fclose(STDERR) 关闭标准I/O流。用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。
 

PHP系统编程--02.PHP守护进程化的更多相关文章

  1. python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程

    python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 目录 python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 ...

  2. PHP程序守护进程化

    一般Server程序都是运行在系统后台,这与普通的交互式命令行程序有很大的区别.glibc里有一个函数daemon.调用此函数,就可使当前进程脱离终端变成一个守护进程,具体内容参见man daemon ...

  3. PHP守护进程化

    什么是守护进程? 一个守护进程通常补认为是一个不对终端进行控制的后台任务.它有三个很显著的特征:在后台运行,与启动他的进程脱离,无须控制终端.常用的实现方式是fork() -> setsid() ...

  4. python并发编程基础之守护进程、队列、锁

    并发编程2 1.守护进程 什么是守护进程? 表示进程A守护进程B,当被守护进程B结束后,进程A也就结束. from multiprocessing import Process import time ...

  5. Python 3 并发编程多进程之守护进程

    Python 3 并发编程多进程之守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemo ...

  6. Linux编程之《守护进程》

    Intro ----- 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常 ...

  7. Linux网络编程学习(四) -----守护进程的建立(第三章)

    本文介绍一个例程daemon_init() #include <sys/types.h> #include <signal.h> #include <unistd.h&g ...

  8. Mac系统的launchd、守护进程daemon(2013笔记整理)

    1. launchd Mac系统下通用的进程管理器,是Mac系统下非常重要的一个进程,一般来说该进程不允许直接以命令行的形式调用.只能通过其控制管理界面,launchctl来进行控制. launchd ...

  9. Linux系统编程(8)—— 进程之进程控制函数fork

    fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事. 一个进程调用fork()函数后,系统先 ...

随机推荐

  1. nginx配置和网站的部署

    环境: CentOS Linux release 7.3.1611 (Core) nginx version: nginx/1.13.4 PHP 5.4.16 (cli) (built: Nov 6 ...

  2. mysql分页的limit优化

    1.很多新人都会很纳闷,为什么我建了索引使用分页还是这么卡.好,现在让我们一步一步去找原因吧. 首先limit本身跟索引没有直接关系. 先建一张商品sku表 create table goods_sk ...

  3. 20145214 《Java程序设计》第7周学习总结

    20145214 <Java程序设计>第7周学习总结 教材学习内容总结 时间的度量 格林威治标准时间(GMT),现已不作为标准时间使用,即使标注为GMT(格林威治时间),实际上谈到的的是U ...

  4. unity像素贪吃蛇

    [ 星 辰 · 别 礼 ] 设计过程: 首先,在之前玩坏控制台做的那个c#贪吃蛇之后,我以为做unity会很简单,但事实比较不如人意...拖了好几天.因为过程中遇到一些问题 蛇身的移动,还是用列表,将 ...

  5. 福大软工1816:Alpha(7/10)

    Alpha 冲刺 (7/10) 队名:Jarvis For Chat 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.完成 ...

  6. lintcode-179-更新二进制位

    179-更新二进制位 给出两个32位的整数N和M,以及两个二进制位的位置i和j.写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串) 注意事项 In the function ...

  7. iOS开发SDWebImage源码解析之SDWebImageManager的注解

    最近看了两篇博客,写得很不错,关于SDWebImage源码解析之SDWebImageManager的注解: 1.http://www.jianshu.com/p/6ae6f99b6c4c 2.http ...

  8. Sqoop使用笔记(转载)

    Sqoop是Apache顶级项目,主要用来在Hadoop和关系数据库中传递数据.通过sqoop,可以方便的将数据从关系数据库导入到HDFS,或将数据从HDFS导出到关系数据库. 关于Sqoop 官网S ...

  9. RT-thread内核之小内存管理算法

     一.动态内存管理 动态内存管理是一个真实的堆(Heap)内存管理模块,可以在当前资源满足的情况下,根据用户的需求分配任意大小的内存块.而当用户不需要再使用这些内存块时,又可以释放回堆中供其他应用分配 ...

  10. service(ServletRequest req, ServletResponse res) 通用servlet 可以接受任意类型的请求 用于扩展

    service(ServletRequest req, ServletResponse res)   通用servlet 可以接受任意类型的请求  用于扩展