Linux php系统的起源原理功能时间

前言

前言

对大家推荐很好使用的Linux php系统,像让大家对Linux
php系统有所了解,然后对Linux
php系统全面讲解介绍,希望对大家有用Linux/Unix下守护进程Daemon)大家都知道,比如我们常用的httpd、mysqld等等,就是常驻内存运行的程序,类似于Windows下的服务。一般守护进程都是使用C/C++来写,就是通过fork生成子进程。

daemon 音标 : [‘di:mən] , 中文含义为守护神或精灵的意思 .
其实它还有个意思 : 守护进程 .

在一个多任务的计算机操作系统中,守护进程(英语:daemon,/ˈdiːmən/或/ˈdeɪmən/)是一种在后台执行的计算机程序。此类程序会被以进程的形式初始化。守护进程程序的名称通常以字母“d”结尾:例如,syslogd就是指管理系统日志的守护进程。

当前台shell下的父进程被杀掉,子进程就转到后台运行,为了不在终端产生输出信息,就通过
syslog等函数来写日志文件。我们知道php是脚本语言,通过php的脚本引擎来执行,所以要做成守护进程比较麻烦。

Daemon程序是一直运行的服务端程序,又称为守护进程。通常在系统后台运行,没有控制终端不与前台交互,Daemon程序一般作为系统服务使用。Daemon是长时间运行的进程,通常在系统启动后就运行,在系统关闭时才结束。一般说Daemon程序在后台运行,是因为它没有控制终端,无法和前台的用户交互。Daemon程序一般都作为服务程序使用,等待客户端程序与它通信。我们也把运行的Daemon程序称作守护进程。

daemon
程序是一直运行的服务端程序,又称为守护进程。通常在系统后台运行,没有控制终端不与前台交互,daemon
程序一般作为系统服务使用。daemon是长时间运行的进程,通常在系统启动后就运行,在系统关闭时才结束。一般说Daemon程序在后台运行,是因为它没有控制终端,无法和前台的用户交互。daemon程序一般都作为服务程序使用,等待客户端程序与它通信。我们也把运行的daemon程序称作守护进程。

我们今天就来结合Unix/Linux的命令来实现我们守护进程的功能。Unix中的nohup命令的功能就是不挂断地运行命令,同时nohup把程序的所有输出到放到当前目录的nohup.out文件中,如果文件不可写,则放到<用户主目录>/nohup.out
文件中。

每个进程都有一个父进程,子进程退出,父进程能得到子进程退出的状态。

通常,守护进程没有任何存在的父进程,且在UNIX系统进程层级中直接位于init之下。守护进程程序通常通过如下方法使自己成为守护进程:对一个子进程运行fork,然后使其父进程立即终止,使得这个子进程能在init下运行。这种方法通常被称为“脱壳”。

那么有了这个命令以后,我们的Linux
php程序就写程shell脚本。使用循环来让我们的脚本一直运行,那么不管我们终端窗口是否关闭,都能够让我们的Linux
php脚本一直运行。当然,当我们的Linux
php进程被杀或者我们的操作系统重启了,自然就会中止了。

守护进程简单地说就是可以脱离终端而在后台运行的进程 .
这在Linux中是非常常见的一种进程 , 比如apache或者mysql等服务启动后 ,
就会以守护进程的方式进驻在内存中 .

系统通常在启动时一同起动守护进程。守护进程为对网络请求,硬件活动等进行响应,或其他通过某些任务对其他应用程序的请求进行回应提供支持。守护进程也能够对硬件进行配置(如在某些Linux系统上的devfsd),运行计划任务,以及运行其他任务。每个进程都有一个父进程,子进程退出,父进程能得到子进程退出的状态。

肯定会问,让我们的Linux
php脚本做了守护进程又有什么用处呢?当然有,比如最典型的作用,能够基本的替代cron的功能,比如我们需要定期实行的某些操作,完全可以交给它来做,不再需要cron。

以PHP为例 , 假如我有个耗时间的任务需要跑在后台 :
将所有mysql中user表中的2000万用户全部导入到redis中做预热缓存 ,
那么这个任务估计一时半会是不会结束的 ,
这个时候就需要编写一个php脚本以daemon形式运行在系统中 , 结束后自动推出 .

守护进程简单地说就是可以脱离终端而在后台运行的进程
. 这在Linux中是非常常见的一种进程 , 比如apache或者mysql等服务启动后 ,
就会以守护进程的方式进驻在内存中
。守护程序是在后台运行的应用程序,而不是由用户直接操作。守护进程的例子是Cron和MySQL。
使用PHP守护进程非常简单,并且需要使用PHP 4.1或更高版本编译参数:–enable-pcntl

当然,如果服务器重启就没有办法了,不过,一般的Unix服务器不是那么容易重启的。另外,我们还可以做一个简单的服务器端的功能,比如做一个能够Telnet过去的服务器,嘿嘿,可以做成一个小后门,不过这样实现稍微有点复杂。

在Linux中 , 大概有三种方式实现脚本后台化 :

假如有个耗时间的任务需要跑在后台 :
将所有mysql中user表中的2000万用户全部导入到redis中做预热缓存 ,
那么这个任务估计一时半会是不会结束的 ,
这个时候就需要编写一个php脚本以daemon形式运行在系统中 ,
结束后自动推出。

例子一:自动生成文件我们现在来做两个例子来证明我们上面的说法。首先第一个是每个三十秒自动生成一个文件,永远执行下去。首必须确保操作系统是Unix或者Linux,比如可以是FreeBSD、Redhat、Fedora或者SUSE什么的。

1 . 在命令后添加一个&符号 , 比如 php task.php & . 这个方法的缺点在于
如果terminal终端关闭 , 无论是正常关闭还是非正常关闭 ,
这个php进程都会随着终端关闭而关闭 ,
其次是代码中如果有echo或者print_r之类的输出文本 ,
会被输出到当前的终端窗口中 .

在Linux中 , 有三种方式实现脚本后台化 :

然后我们必须确保我们的Linux php脚本引擎是在
/usr/local/php/bin/php,具体路径可以按照你实际路径来写,如果没有脚本引擎,请自行安装。比如当前目录是
/home/heiyeluren/,那么我们使用vi或者其他编辑器编写一个叫做php_daemon1.php的文件:
$ vi php_daemon1.php
然后写入如下代码:

2 . 使用nohup命令 , 比如 nohup php task.php & . 默认情况下 ,
代码中echo或者print_r之类输出的文本会被输出到php代码同级目录的nohup.out文件中
. 如果你用exit命令或者关闭按钮等正常手段关闭终端 , 该进程不会被关闭 ,
依然会在后台持续运行 . 但是如果终端遇到异常退出或者终止 ,
该php进程也会随即退出 . 本质上 , 也并非稳定可靠的daemon方案 .

1 . 在命令后添加一个&符号

比如php task.php &. 这个方法的缺点在于
如果terminal终端关闭 , 无论是正常关闭还是非正常关闭 ,
这个php进程都会随着终端关闭而关闭 ,
其次是代码中如果有echo或者print_r之类的输出文本 ,
会被输出到当前的终端窗口中 。

#! /usr/local/php/bin/php  <? set_time_limit(0);  while(1)  {   @fopen("test_".time().".txt","w");   sleep(30);  }  ?> 

3 . 使用fork和setsid , 我暂且称之为 : *nix解决方案 . 具体看下代码 :

2 . 使用nohup命令

比如 nohup php task.php & .
默认情况下 ,
代码中echo或者print_r之类输出的文本会被输出到php代码同级目录的nohup.out文件中
. 如果你用exit命令或者关闭按钮等正常手段关闭终端 , 该进程不会被关闭 ,
依然会在后台持续运行 . 但是如果终端遇到异常退出或者终止 ,
该php进程也会随即退出 . 本质上 , 也并非稳定可靠的daemon方案 。

3 .通过pcntlposix扩展实现

编程中需要注意的地方有:

  • 通过二次pcntl_fork()以及posix_setsid让主进程脱离终端
  • 通过pcntl_signal()忽略或者处理SIGHUP信号
  • 多进程程序需要通过二次pcntl_fork()或者pcntl_signal()忽略SIGCHLD信号防止子进程变成
    Zombie 进程
  • 通过umask()设定文件权限掩码,防止继承文件权限而来的权限影响功能
  • 将运行进程的STDIN/STDOUT/STDERR重定向到/dev/null或者其他流上

daemon有如下特征:

  • 没有终端
  • 后台运行
  • 父进程 pid 为1

想要查看运行中的守护进程可以通过ps -ax或者ps -ef查看,其中-x表示会列出没有控制终端的进程。

然后保存并且退出vi,然后赋予php_daemon1.php文件可执行权限:
$ chmod +x /home/heiyeluren/php_daemon1.php

总结

fork 系统调用

fork系统调用用于复制一个与父进程几乎完全相同的进程,新生成的子进程不同的地方在于与父进程有着不同的
pid
以及有不同的内存空间,根据代码逻辑实现,父子进程可以完成一样的工作,也可以不同。子进程会从父进程中继承比如文件描述符一类的资源。

PHP
中的pcntl扩展中实现了pcntl_fork()函数,用于在 PHP 中 fork
新的进程。

然后再让我们的脚本再后台执行,执行如下命令:
$ nohup /home/heiyeluren/php_daemon1.php &

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

setsid 系统调用

setsid系统调用则用于创建一个新的会话并设定进程组
id。这里有几个概念:会话进程组

  在 Linux
中,用户登录产生一个会话,一个会话中包含一个或者多个进程组,一个进程组又包含多个进程。每个进程组有一个组长(Session Leader),它的 pid
就是进程组的组
id。进程组长一旦打开一个终端,这一个终端就被称为控制终端。一旦控制终端发生异常,会发出信号到进程组组长。

  后台运行程序(如 shell
中以&结尾执行指令)在终端关闭之后也会被杀死,就是没有处理好控制终端断开时发出的SIGHUP信号,而SIGHUP信号对于进程的默认行为则是退出进程。

调用setsid系统调用之后,会让当前的进程新建一个进程组,如果在当前进程中不打开终端的话,那么这一个进程组就不会存在控制终端,也就不会出现因为关闭终端而杀死进程的问题。

PHP
中的posix扩展中实现了posix_setsid()函数,用于在 PHP
中设定新的进程组。

记得最后加上 &
符号,这样才能够跑到后台去运行,执行上述命令后出现如下提示:

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website