我找不到这个问题的答案是完全没有成功的。希望有人可以提供帮助。
我有一个PHP脚本(一个特定的WordPress模板),可以在用户点击图像时自动导入和处理图像。问题是图像处理占用大量内存,特别是如果多个用户同时访问模板并启动图像处理。由于这个原因,我的服务器多次崩溃。
我的解决方案是,如果图像处理功能已经运行,则不执行该功能。在函数开始运行之前,我会检查一个名为image_import_running的数据库条目,看它是否设置为false。如果是,则该函数运行。函数的第一件事就是将image_import_running设置为true。然后,在完成所有操作后,我将其设置为false。
它在理论上很有效。该网站没有崩溃,我可以告诉你。但它有两个主要问题:
如果用户在加载页面时关闭页面,则脚本永远不会完成处理图像,因此永远不会将image_import_running设置为false。在手动将图像设置为false之前,模板将永远不会再次处理图像。
如果脚本在处理图像时超时 - 如果队列中有很多图像,这很有可能 - 你的问题基本上与1号相同:脚本永远不会达到目的它将image_import_running设置为false。
为了处理1号(我意识到的两个问题中的第一个),我在脚本中添加了ignore_user_abort(true)
。它有用吗?我不知道,因为2号仍然是一个问题。那就是我难倒的地方。
如果我可以询问服务器脚本是否正在运行,我可以这样做:
if($import_running && $script_not_running) {
$import_running = false;
}
但是如何设置$script_not_running
变量?打败我。
我和你分享了这整个故事,以防你有其他明智的解决方案。
答案 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.
?>