如果脚本已经在运行,请不要运行脚本

时间:2013-08-07 21:19:47

标签: php wordpress

我找不到这个问题的答案是完全没有成功的。希望有人可以提供帮助。

我有一个PHP脚本(一个特定的WordPress模板),可以在用户点击图像时自动导入和处理图像。问题是图像处理占用大量内存,特别是如果多个用户同时访问模板并启动图像处理。由于这个原因,我的服务器多次崩溃。

我的解决方案是,如果图像处理功能已经运行,则不执行该功能。在函数开始运行之前,我会检查一个名为image_import_running的数据库条目,看它是否设置为false。如果是,则该函数运行。函数的第一件事就是将image_import_running设置为true。然后,在完成所有操作后,我将其设置为false。

它在理论上很有效。该网站没有崩溃,我可以告诉你。但它有两个主要问题:

  1. 如果用户在加载页面时关闭页面,则脚本永远不会完成处理图像,因此永远不会将image_import_running设置为false。在手动将图像设置为false之前,模板将永远不会再次处理图像。

  2. 如果脚本在处理图像时超时 - 如果队列中有很多图像,这很有可能 - 你的问题基本上与1号相同:脚本永远不会达到目的它将image_import_running设置为false。

  3. 为了处理1号(我意识到的两个问题中的第一个),我在脚本中添加了ignore_user_abort(true)。它有用吗?我不知道,因为2号仍然是一个问题。那就是我难倒的地方。

    如果我可以询问服务器脚本是否正在运行,我可以这样做:

    if($import_running && $script_not_running) {
        $import_running = false;
    }
    

    但是如何设置$script_not_running变量?打败我。

    我和你分享了这整个故事,以防你有其他明智的解决方案。

7 个答案:

答案 0 :(得分:1)

尝试使用 ignore_user_abort(true);即使此人离开并关闭浏览器,它也会继续运行。

您可能还想在db记录中放入一个数字而不是true false,并设置可以一起运行的最大进程数

答案 1 :(得分:1)

正如其他人所建议的那样,最好将图像处理移出请求本身。

作为临时“修复”,当处理作业开始时(例如image_import_running),在image_import_commenced旁边存储时间戳。这是一种非常粗略的机制,但如果您知道作业在超时之前可以运行的最长时间,则脚本可以检查该时间段是否已经过去。

例如,如果image_import_running仍然为真,但当前时间超过了image_import_commenced后的10分钟,则无论如何都要运行处理。

答案 2 :(得分:1)

如果设置一个具有到期时间的瞬态,那将会限制操作?

if(!get_transient( 'import_running' )) {
  set_transient( 'import_running', true, 30 ); // set a 30 second transient on the import.
  run_the_import_function();
}

答案 3 :(得分:1)

我宁愿将作业存储到数据库中,标记它挂起并设置一个cron作业来一次执行一个作业的处理。

答案 4 :(得分:0)

对于我,我只使用这个简单的想法和文本文档。例如run.txt文件
在顶部脚本中使用:

if((file_get_contents('run.txt') != 'run'){ // here the script will work
$file = fopen('run.txt', 'w+');
fwrite($file, 'run');
fclose('run.txt');
}else{
exit(); // if it find 'run' in run.txt the script will stop
}

并将其添加到脚本文件的末尾

$file = fopen('run.txt', 'w+');
fwrite($file, ''); //will delete run word for the next try ;)
fclose('run.txt');

这将通过检查runt.txt内容来检查脚本是否已经工作 如果run.txt中存在运行单词,则不会运行

答案 5 :(得分:0)

运行cron绝对是一个更好的解决方案。将URL存储在表中的想法很好。

要回答原始问题,您可以使用exec运行ps auxwww命令(检查此页面:How to get list of running php scripts using PHP exec()?)并将您的函数移动到单独的php文件中。

exec("ps auxwww|grep myfunction.php|grep -v grep", $output);

答案 6 :(得分:-2)

只需在脚本顶部添加以下内容即可。

<?php
    // Ensures single instance of script run at a time.
    $fileName = basename(__FILE__);
    $output = shell_exec("ps -ef | grep -v grep | grep $fileName | wc -l");
    //echo $output; 
    if ($output > 2)
    {
        echo "Already running - $fileName\n";
        exit;   
    }

    // Your php script code.
?>