PHP锁定/确保给定脚本在任何给定时间仅运行一次 [英] PHP locking / making sure a given script is only running once at any given time
问题描述
我正在尝试编写一个PHP脚本,以确保在任何给定时间仅运行该脚本的一个实例.所有这些关于不同的锁定方式,比赛条件等等等等的讨论都在给我带来麻烦.
I'm trying to write a PHP script that I want to ensure only has a single instance of it running at any given time. All of this talk about different ways of locking, and race conditions, and etc. etc. etc. is giving me the willies.
对于是否使用锁文件,使用信号灯,使用MySQL锁等等等,我感到困惑.
I'm confused as to whether lock files are the way to go, or semaphores, or using MySQL locks, or etc. etc. etc.
谁能告诉我:
a)实现此目标的正确方法是什么?
a) What is the correct way to implement this?
AND
b)向我介绍一个PHP实现(或易于移植到PHP的东西?)
b) Point me to a PHP implementation (or something easy to port to PHP?)
推荐答案
一种方法是将php函数 flock 与虚拟文件一起使用,该虚拟文件将充当看门狗.
One way is to use the php function flock with a dummy file, that will act as a watchdog.
在工作开始时,如果文件出现 LOCK_EX 标志,则可以退出或等待.
On the beginning of our job, if the file raise a LOCK_EX flag, exit, or wait, can be done.
Php羊群文档: http://php.net/manual/zh/function.flock.php
对于此示例,必须首先创建一个名为 lock.txt 的文件.
For this examples, a file called lock.txt must be created first.
示例1,如果另一个孪生进程正在运行,它将正确退出,不重试,给出状态消息.
Example 1, if another twin process is running, it will properly quit, without retrying, giving a state message.
如果无法访问文件 lock.txt ,则会抛出错误状态.
It will throw the error state, if the file lock.txt isn't reachable.
<?php
$fp = fopen("lock.txt", "r+");
if (!flock($fp, LOCK_EX|LOCK_NB, $blocked)) {
if ($blocked) {
// another process holds the lock
echo "Couldn't get the lock! Other script in run!\n";
}
else {
// couldn't lock for another reason, e.g. no such file
echo "Error! Nothing done.";
}
}
else {
// lock obtained
ftruncate($fp, 0); // truncate file
// Your job here
echo "Job running!\n";
// Leave a breathe
sleep(3);
fflush($fp); // flush output before releasing the lock
flock($fp, LOCK_UN); // release the lock
}
fclose($fp); // Empty memory
示例2 ,我们希望进程等待队列之后的执行(如果有):
Example 2, we wants the process to wait, for an execution after the queue, if any:
<?php
$fp = fopen("lock.txt", "r+");
if (flock($fp, LOCK_EX)) { // acquire an exclusive lock
ftruncate($fp, 0); // truncate file
// Your job here
echo "Job running!\n";
// Leave a breathe
sleep(3);
fflush($fp); // flush output before releasing the lock
flock($fp, LOCK_UN); // release the lock
}
fclose($fp);
通过在脚本结束时创建和擦除文件,也可以将打开进入 x 模式.
It is also doable with fopen into x mode, by creating and erasing a file when the script ends.
创建并开放以仅用于编写;将文件指针放在文件的开头.如果文件已经存在,则调用fopen()将失败,返回FALSE
Create and open for writing only; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning FALSE
http://php.net/manual/en/function.fopen.php
这篇关于PHP锁定/确保给定脚本在任何给定时间仅运行一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!