在Apache/PHP中,如何运行一个独立的进程,并在linux上Apache重启后继续运行

在Apache/PHP中,如何运行一个独立的进程,并在linux上Apache重启后继续运行,php,linux,apache,process,Php,Linux,Apache,Process,我正在尝试启动一个php(在apache下)进程(通过从浏览器调用apache),该进程将在关闭apache服务器(sudo服务apache2 stop)后继续运行。即使我确保创建的进程没有父进程(父进程1),并且有自己的会话,但在我停止apache(或重新启动apache)时,进程还是会死掉 我创建了一个test.php文件: <?php exec('setsid nohup sleep 1000 > /dev/null 2>/dev/null &'); ?>

我正在尝试启动一个php(在apache下)进程(通过从浏览器调用apache),该进程将在关闭apache服务器(sudo服务apache2 stop)后继续运行。即使我确保创建的进程没有父进程(父进程1),并且有自己的会话,但在我停止apache(或重新启动apache)时,进程还是会死掉

我创建了一个test.php文件:

<?php
exec('setsid nohup sleep 1000 > /dev/null 2>/dev/null &');
?>
睡眠过程结束了。
当进程不属于其组或会话,并且进程不是子进程时,如何杀死该进程?

Apache可能会有一个生成进程的列表,并单独杀死它们,而不是作为一个组杀死它们。在这种情况下,列表中的所有进程都将
kill(2)
ed。但有关可能性,请参见下面的下一段

查看
kill(2)
系统调用的手册页。在错误部分,失败的可能性只有:

  • EINVAL
    ,表示传递了无效的信号号。这不适用

  • ESRCH
    ,进程(或进程组)不存在。也不适用

  • EPERM
    ,您没有发送信号的权限。这适用于此处,但您可以向其发送信号的唯一进程(与进程层次结构或父级关系无关)是使用实际/保存的用户id等于发送方进程的有效用户id运行的进程。因此,由于Apache有一个它启动的所有进程的注册表,所以它能够终止进程是正常的

无论如何,您是否尝试过创建一个流程,从该流程创建一个子流程,并在孙子子流程中执行
setsid
?这样,Apache进程就不可能在派生进程列表中注册它。我没有试过,但它可能会起作用

从FreeBSD
kill(2)
手册页面:

允许进程向指定的进程发送信号 通过pid,用户必须是超级用户,或的真实或保存的用户ID 接收过程必须与服务器的真实或有效用户ID匹配 发送过程。单一异常是信号
SIGCONT
,它可能 始终使用与发件人相同的会话ID将其发送到任何进程

(重点是我的)在linux中,除了

。。。(如果发送进程)在目标进程的用户名称空间中具有
CAP_KILL
功能


但这不适用于这里。

“我正在尝试从php(+apache)启动一个进程”-您是否通过浏览器,通过apache调用您的脚本?没错。简单的apache服务器,调用我在问题中编写的php脚本。cron是选项吗?您可以每分钟检查一次数据库表中是否有条目,然后对其进行处理。如果是关于文件的,想象一下为什么要使用cron?为什么是DB?我只想要一个简单的过程(孤儿?)将继续活着。这很简单。我不明白apache是如何拥有终止进程的权利/特权的。也许apache会保存一个php发送的进程的PID列表,并在关闭期间逐个杀死它们?尝试创建一个进程,分叉它并杀死父进程。那么就不应该有任何与Apache的连接了。我记得我在类似的情况下使用过这种方法(记不清具体是什么)。基本上,您可以通过跟踪其
ppid
来判断Apache生成了哪些进程,但如果父进程不再存在,则会中断该链。我尝试修改php exec()命令以运行执行“setsid nohup sleep 1000”(2级)的.sh脚本,但我没有尝试创建进程,这将创建另一个子流程,然后使用setsid创建另一个子流程。需要这么多级别吗?两个级别还不够吗?
sudo service apache2 stop