有没有一种可移植的方法来设置flock() 的超时时间?

Posted

技术标签:

【中文标题】有没有一种可移植的方法来设置flock() 的超时时间?【英文标题】:Is there a portable way to put a timeout on flock()? 【发布时间】:2017-04-04 06:43:28 【问题描述】:

flock()phpportable 咨询文件锁定功能。他们明确宣传它甚至可以在 Windows 下工作:

flock() 允许您执行一个简单的读取器/写入器模型,该模型可用于几乎所有平台(包括大多数 Unix 衍生产品甚至 Windows)。

我想在阻塞flock() 上设置一个便携式超时(并且使用LOCK_NB 选项不忙于等待工作)。在 UNIX 中,这可以通过设置一个发送SIGALRM 的警报来简单地实现:

pcntl_signal(SIGALRM, function() );
pcntl_alarm(3);
try 
    if (!flock($handle, LOCK_EX)) 
        throw new \Exception("Timeout");
    
 finally 
    pcntl_alarm(0);
    pcntl_signal_dispatch();
    pcntl_signal(SIGALRM, SIG_DFL);

有没有一种可移植的方式来设置阻塞flock() 的超时时间?如果有,怎么做?

【问题讨论】:

LOCK_NB + 循环 + usleep? > 并且使用 LOCK_NB 选项无需忙于等待工作 php.net/flock @zerkms 我确定他已经看过了……实际的答案是在 PHP 中没有办法做到这一点。 Windows 有报警功能,但它没有通过 PHP 中的任何扩展公开。 @bwoebi 好吧,他们决定玩迂腐。我也是 - flock 可以做的所有事情都在该页面(或 php 源代码)中进行了解释。 PS:奇怪的是,甚至想要终止进程而不是优雅地处理它(即使是繁忙的等待循环) 【参考方案1】:

我认为没有任何方法可以在没有繁忙的等待/轮询循环的情况下在 Windows 上执行此操作。

PHP 在 Windows 上使用LockFileEx 实现flock(请参阅flock_compat.c:132)。正如您从这些类似的问题中看到的那样,无法在LockFileEx 上设置超时或取消等待LockFileEx 请求的进程(即,对于此用例,没有等效于SIGALRM 信号):

    LockFile with timeout?(2011 年问)

Q) 如果我想等待超时的文件锁定,我该怎么做?

...

A) 编写一个小循环来检查返回码

    "LockFileEx can't time out it just hangs" 来自 microsoft.public.win32.programmer.kernel 邮件列表,1997 年

Q) 有谁知道让 LockFileEx 超时的方法吗?

...

A) 你只能让它立即失败、休眠并循环返回 直到达到某个重试限制。

【讨论】:

以上是关于有没有一种可移植的方法来设置flock() 的超时时间?的主要内容,如果未能解决你的问题,请参考以下文章

是否有一种可移植的(C++ 标准)方法来计算前一个对齐的指针?

标准 C++ 中是不是有一种可移植的方式来检索主机名?

是否有一种可移植的方式来定义 INT_MAX?

是否有一种可移植的方式来获取 Python 中的当前用户名?

是否有一种可移植的方式在 Makefile 中制作可移植的可选依赖项?

PHP检查文件是不是被flock()锁定?