【问题标题】:What is the reason for flock() to return FALSE?flock() 返回 FALSE 的原因是什么?
【发布时间】:2016-03-18 12:16:47
【问题描述】:

PHP 手册说调用flock 如果锁定成功则返回TRUE,否则返回FALSE。如果文件被其他进程阻塞,则flock应该等到它被解除阻塞(因为我们不使用LOCK_NB)。文档中没有关于超时的内容,它可以中断等待,因此显然flock会无限等待直到获得锁定。

但有时我在多线程脚本中从flock() 得到FALSE。这是什么原因?

【问题讨论】:

  • 可能是因为“所有访问程序都必须使用相同的锁定方式,否则将无法正常工作”?
  • False 如果除了“它已经获得”之外没有获得锁的原因,例如例如“操作系统不允许我检查文件是否被锁定”。
  • 如果您想获得任何信息而不是盲目(并且不太可能回答您)猜测,您必须提供更多详细信息,例如您的操作系统、您尝试 flock() 的资源类型并进一步阐明您所说的“有时”是什么意思。
  • 多线程 PHP?虽然它可能是非常不寻常的,但在这种情况下,你应该以这种不经意的方式提及它,这很奇怪。尤其是当它经常与异步 I/O 并驾齐驱时(这对锁定有进一步的复杂性)。你能澄清一下你为多线程使用的扩展吗?
  • 我在 FreeBSD 下使用 pcntl_fork()。一般来说,我想知道,如果flock 应该等到锁空闲,怎么可能得到FALSE。

标签: php


【解决方案1】:

我最近遇到了类似的问题并做了一个小研究。如果您查看source code of the PHP flock function,您可以看到实现取决于编译代码的操作系统。

对于 *nix 系统有:

ret = fcntl(fd, operation & LOCK_NB ? F_SETLK : F_SETLKW, &flck);

表示使用了操作系统级别的 fcntl 函数。

Manual for fcntl 说:

F_SETLKW (结构群 *)

与 F_SETLK 一样,但如果文件上持有冲突锁,则等待该锁被释放。 如果在等待时捕获到信号,则调用被中断并且(在信号处理程序返回后)立即返回(返回值 -1 和 errno 设置为 EINTR;参见 signal(7))。

【讨论】:

    【解决方案2】:

    另一个原因可能是 php.ini 中的“安全”限制。

    所以还要检查phpinfo() flock 是否列在disabled_functions 列表中:

    【讨论】:

      猜你喜欢
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 2014-11-27
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 2011-05-15
      相关资源
      最近更新 更多