提问人:Pekka 提问时间:10/22/2010 最后编辑:CommunityPekka 更新时间:10/22/2010 访问量:2935
为什么在PHP中锁定如此混乱?
Why is locking such a mess in PHP?
问:
一位 SO 用户提出了一个问题,其答案实际上是“使用锁定机制”。
在研究我的答案时,我发现 PHP 中似乎没有简单的、进程间可靠的锁定机制。flock() 有一个很大的 FAT 警告:
在某些操作系统上,flock() 是在进程级别实现的。当使用像 ISAPI 这样的多线程服务器 API 时,您可能无法依靠 flock() 来保护文件免受在同一服务器实例的并行线程中运行的其他 PHP 脚本的影响!
这个问题中的讨论非常深入地探讨了这个问题,但只提出了相当复杂的解决方案:使用 RAM 磁盘或 Memcache。
唯一看起来不错的东西是 mySQL 的 GET_LOCK()。
所以我的问题是:真的是这样吗?PHP中真的没有简单、直接、跨平台的安全锁定系统吗?一个是原子的,如果所有者进程死亡,它将释放锁,并且不需要大量的设置工作?
答:
PHP不是一个永久的过程,而是一个短期的线程,因为它经常被创建和销毁。根据实现的不同,它 多个 PHP 进程可能在同一代码上同时运行。
我相信各种PHP实现(mod_php,PHP CLI等)使PHP中的锁定和线程变得困难。
评论
不同意 Wernight 的回答。是的,网络的东西非常相关 - 但限制因素是操作系统的行为方式。
在 PHP 支持的所有操作系统上,只有 2 种文件锁定选择——阻塞或非阻塞。最终,PHP 必须使用操作系统文件锁定机制来避免与访问相同文件的非 PHP 代码发生冲突。如果使用阻塞锁,则 PHP 脚本可能会被无限期阻塞,等待锁被释放 - 对于 Web 应用程序来说,这不是一个好方案。OTOH 如果你做了一个非阻塞的锁调用,但它失败了 - 你接下来该怎么做 - 你是否只是等待一个随机的时间,让你所有的PHP脚本都试图抓住锁?
解决该问题的唯一实用方法是使用超时的排队锁定请求 - 但 AFAIK 本身没有操作系统提供该功能。我自己编写了这样的代码 - 用于专用的 Web 服务器,因此允许其他程序访问没有问题,但是我希望可以使用 inotify 扩展到系统范围的强制锁定系统。
评论
lockfile
,但这几乎不是 PHP 解决方案。