【问题标题】:Synchronized functions in PHPPHP中的同步函数
【发布时间】:2010-12-28 21:41:46
【问题描述】:

有没有办法让 PHP 中的函数同步,以确保两个或多个 webuser 不能同时执行同一个函数?

【问题讨论】:

  • 我认为您需要在此处提供更多信息。您尝试执行的函数不是线程安全的吗?
  • 这个帖子有点老了,但我认为这是一个很好的答案:Stackoverflow

标签: php


【解决方案1】:

我认为您可以通过使用sem_acquire 获取信号量(进入关键部分)和sem_release 来释放锁来实现相同的效果(如果可用)。

【讨论】:

【解决方案2】:

您可以使用外部锁定 - 例如,通过flock 锁定文件。在某处创建一个文件并让脚本锁定它。您也可以使用semaphores,但这些仅适用于 Unix。

【讨论】:

  • 我喜欢这个答案。 Here 是“flock”方法的一个例子。
【解决方案3】:

我想不出您可能面临的任何问题。但是,我曾经必须编写一个 PHP 脚本来执行一些复杂的计算,并且我必须确保它不是由两个用户同时执行的。为此,我在脚本开始时创建了一个空文件,并在计算完成时将其删除。当然,脚本会在开始计算之前检查文件是否存在。

【讨论】:

  • 不过,数据库可能会更快。
  • 考虑这一点:处理 1 检查文件是否存在且不存在。然后进程一个时间片结束,它是进程二轮它检查te ile是否存在,因为进程二还没有创建它。两个进程将同时运行!您的解决方案降低了风险,但并没有消除风险。您应该按照 Alfred 的建议使用 sem_aquire。
  • @Oliver A.:请记住,我只是描述了我很久以前使用的解决方案。我还没有说这是最好的。
  • 巴兰。我从来没有打算攻击/侮辱你。我只是想指出,这并不像听起来那么节省。
【解决方案4】:

请注意,本地文件锁定和信号量仅在您拥有一台 Web 服务器时才有效。如果您的脚本由多个负载平衡的服务器托管,您将不得不找到一些其他锁定机制,例如一台机器上的专用“锁定服务器”或某种通过 NFS 锁定的文件。

【讨论】:

    【解决方案5】:

    更多关于你为什么需要锁的细节会很好。如果您遇到用户的数据库交互相互冲突的问题,您应该考虑在数据库代码中使用事务,以便数据库自动处理复杂的更改。

    例如:我使用 Symfony 和 Doctrine ORM,所以我的提交代码通常看起来像这样:

    $conn = Doctrine_Manager::connection();
    $conn->beginTransaction();
    try {
    // .. database code ..
        $conn->commit();
    } catch(Doctrine_Exception $ex) {
        $conn->rollback();
        // additional exception handling
    }
    

    现在,如果用户碰巧同时修改同一条记录,这将不会阻止用户互相攻击;但是,它将确保数据库保持一致 - 即用户 A 的更改生效或用户 B 的更改生效,但绝不会根据数据库的情绪而出现用户 A 和用户 B 的更改的大杂烩。

    【讨论】:

      【解决方案6】:

      过去,我在数据库中的记录上创建了简单的锁。如果您正在处理现有记录,则可以存储其类型、id 和锁定时间。确保 type 和 id 是数据库表(或缓存)的键。当您启动该过程时,您以不会擦除现有锁的方式获取锁。如果有过期的锁,就拿去吧。如果存在尚未过期的现有锁,则无法启动进程(队列或返回)。如果没有锁,或者存在已过期的锁,那么您就是黄金。你现在有了锁。完成后,释放锁。

      您可以将这种系统绑定到数据库中已有的记录,为正在进行的工作创建新表,甚至使用外部缓存。

      【讨论】:

        猜你喜欢
        • 2012-09-11
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-25
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多