【问题标题】:lock file between C and php在 C 和 php 之间锁定文件
【发布时间】:2011-01-25 16:41:14
【问题描述】:

虽然标题提到了文件,但它不一定是文件。任何锁定机制都可以。

情况如下:我有一个用 C 编写的守护进程,以及一个用 php 编写的网页。我想有一种相互锁定的方式,这样在某些情况下,C 守护进程会锁定一个文件,php 检测到这种情况并告诉客户端系统正忙。

有没有简单的方法可以做到这一点?

谢谢,

【问题讨论】:

    标签: php c locking mutual-exclusion


    【解决方案1】:

    flock 做得很好。

    在您的 PHP 脚本中,使用 非阻塞锁

    $fd = fopen('/var/run/lock.file', 'r+');
    if (!flock($fd, LOCK_SH | LOCK_NB, $wouldblock) && $wouldblock) {
        // buzy
    }
    

    LOCK_NB 标志使此调用非阻塞。如果文件被独占锁定,它将立即返回。将允许多个页面同时锁定文件。

    你可以释放锁

    flock($fd, LOCK_UN);
    

    在您的 C 守护程序中,使用阻塞和排他锁:

    flock(fd, LOCK_EX); // This will wait until no page has locked the file
    

    参见 PHP 的 flock() 文档和 C 的 one

    【讨论】:

      【解决方案2】:

      你可以让你的守护进程在忙的时候创建一个文件,不忙的时候删除它,然后在 PHP 中执行如下操作:

      if (file_exists('/path/to/file')) {
          echo 'System busy';
      }
      

      【讨论】:

      • 比每次都访问数据库要容易得多。只要守护程序在锁定期结束后小心删除文件,这很可能是最简单和最防故障的选项。 +1
      • mfonda:这看起来可能是竞争条件的受害者。没有?
      • 这个问题是守护进程可以在 file_exits() 调用期间启动,并在调用之后或页面执行期间的任何时间创建文件。
      • @lang2 @user576875 是的,看起来你是对的——user576875 的解决方案是正确的方法。
      【解决方案3】:

      如果您的 PHP 应用程序是数据库驱动的,应该很容易更新该数据库的某个列以指示“系统繁忙”。

      您的 cronjob 将设置和重置此标志,您的 PHP 应用程序可以读取它的值。

      【讨论】:

        【解决方案4】:

        您是否只想让 PHP 检测到守护程序正忙?还是您真的希望他们互相等待?使用独占锁的缺点是 C 守护程序必须等待所有 PHP 实例完成其工作,然后才能获取其锁并继续。

        如果您只是想检测 C 守护程序是否繁忙(即,仅在一个方向上),则只需测试是否存在繁忙的令牌文件(或信号量,或共享内存对象 - 取决于平台)可能是一个更好的选择。然而,创建文件往往比在共享内存中设置一个简单的标志更昂贵。

        【讨论】:

        • 只检测守护进程是否忙。但是文件的好处是它是持久的。我不确定您是否可以拥有持久信号量或共享内存?
        • 持久是指在重新启动后吗?还是跨流程生命周期?为什么不让守护进程创建一个客户端在启动时都附加到的共享内存区域。他们可以在那里检查“忙碌”标志。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        • 2012-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多