0

我有几个脚本运行了很长时间(6 个多小时)。它们都包含一个执行此操作的主循环,以及一个已注册的关闭函数,该函数触发了一个 mysql 查询以宣布该过程为“完成”。

我决定在这些主循环中使用 pcntl_fork() ,将每一轮作为不同的进程运行,以使整个脚本更快地完成。

它工作正常,但是,每个子进程仍然注册了关闭功能。因此,每次子进程完成时,它都会调用 mysql 查询并将脚本宣布为完成。如何为子进程禁用该关闭功能,但为父进程保持活动状态?

示例代码以了解发生了什么:

  • 常见的.php

    register_shutdown_function('shutdown');
    function shutdown()
    {   global $objDb,$arg_id ;
    
           echo "\n\n Executing queue process shutdown function.";
           $objDb->query("UPDATE queue_args SET done='1' WHERE id='{$arg_id}'"); 
    }
    
  • 循环.php

    include('common.php');
    for ($i=1;$i<=200;$i++){    
           $pid = pcntl_fork(); 
           if (!$pid) {
               //child proccess - do something without calling the shutdown function
               posix_kill(getmypid(),9);
           } 
    }  exit(); //this is when the shutdown function should eventually be called
    

谢谢

4

2 回答 2

2

您可以在 if 中注册关闭功能,如下所示:

if ($pid) {
    if(!$registered) {
        $registered = true;
        register_shutdown_function('shutdown');
    }
}else{
    //child proccess - do something without calling the shutdown function
    posix_kill(getmypid(),9);
} 
于 2012-08-15T08:53:21.680 回答
0

你不能。

您可以在分叉后在子进程中设置一个标志并在关闭函数中对其进行轮询 - 如果已设置,则提前返回。或者在你 fork 之前存储父 pid,并且在关闭函数中,如果那不是当前 pid,则提前返回。或者在fork之后在父进程中注册函数。

if (!$pid) { posix_kill(getmypid(),9); }

这是防止在子进程中调用关闭函数的非常糟糕的方法 - 但具有各种其他含义 - PHP 不会干净地关闭,缓冲区不会被刷新。也许你只需要这样做:

#!/usr/bin/php
<?php

$arg_id = exec('task_which_forks.php');
exec("queue_clean_up.php $arg_id");
于 2012-08-15T08:54:28.333 回答