2
我想使用独占/共享,这两个阻塞和非阻塞锁,如在flock()
中发现的。这怎么能用信号量来实现呢?PHP非阻塞排他锁
我想使用独占/共享,这两个阻塞和非阻塞锁,如在flock()
中发现的。这怎么能用信号量来实现呢?PHP非阻塞排他锁
这取决于用例。
如果您只在一台服务器上,请使用锁定文件。
function doSomething() {
$file = /temp/path/somthing.lock;
if (file_exists($file)) {
return false;
}
touch($file);
// Safely mess with things
unlink($file);
}
如果您有多个网络服务器,例如在负载均衡器的后面,同样的事情可以通过在mysql中使用表来完成。
function doSomething() {
$query = "SELECT * FROM locks WHERE name='something'");
$res = mysqli_query($query);
if (mysql_num_rows($res) > 0) {
return false;
}
$query = "INSERT INTO locks (name) VALUES ('something')";
mysqli_query($query);
// Safely mess with things
$query = "DELETE FROM locks WHERE name='something'");
mysqli_query($query);
}
Memcache是多机支持的另一个明显的候选人。
您不应该使用ACP,因为它仅用于缓存。这意味着当ACP存储被删除时您无法控制,这可能随时发生。
您也可以使用信号量,但是如果您使用多个服务器,则与锁定文件相同的警告也适用。
我会建议创建lock($key)
,is_locked($key)
和release($key)
函数,然后在整个项目中宗教地使用它们。这样你就可以开始使用锁定文件(快速实现),但随后升级到更好的东西,而无需编辑其余的代码。如果你想变得很花哨,你可以将它们作为一个记录器对象的方法来实现,并将它们放入代码的已知位置。
Tnx的例子,但我怕他们受竞争条件? http://en.wikipedia.org/wiki/Race_condition – 2013-03-23 15:11:40
嗯,是的,从某种意义上说,他们是。然而,这不是因为这些例子,而是IP协议的副作用,因此没有对时间进行保证。您可以做的最好的做法是阻止多个请求通过。 – cmc 2013-03-25 14:59:59
@cmc什么? IP的网站效应?对于MySQL,您只需在'locks.name'上拥有一个UNIQUE索引,并且成功创建该记录的第一个客户端可以保留该锁。任何进一步的请求都将导致重复的密钥错误。 – Shi 2013-05-16 21:43:56