使用 PHP 的同步功能

问题描述 投票:0回答:5

如何使 PHP 中的函数同步,以便同一个函数不会同时执行?第二个用户必须等待第一个用户完成该功能。然后第二个用户可以执行该功能。

谢谢

php synchronization synchronized
5个回答
16
投票

这基本上可以归结为在函数被锁定的地方设置一个标志,并且在第一个调用者从该函数返回之前无法执行。 这可以通过多种方式完成:

  • 使用锁定文件(第一个函数锁定文件名“f.lok”,第二个函数检查锁定文件是否存在并根据该评估执行或不执行)
  • 在数据库中设置标志(不推荐)
  • 按照@JvdBerg的建议使用信号量(最快)

编写并发应用程序时,请务必注意竞争条件和死锁!

更新 使用信号量(未测试):

<?php

define('SEM_KEY', 1000);

function noconcurrency() {
    $semRes = sem_get(SEM_KEY, 1, 0666, 0); // get the resource for the semaphore

    if(sem_acquire($semRes)) { // try to acquire the semaphore. this function will block until the sem will be available
        // do the work 
        sem_release($semRes); // release the semaphore so other process can use it
    }
}

PHP 需要使用 sysvsem 支持进行编译才能使用 sem_* 函数

这是在 PHP 中使用信号量的更深入教程:

http://www.re-cycledair.com/php-dark-arts-semaphores


12
投票

您正在寻找 信号量

请记住,使用信号量(或任何其他阻塞机制)可能会产生严重的性能问题,因为信号量启动时无法处理请求。


0
投票

我的头顶上:

  • 函数检查名为 isFunctionRunning 的数据库字段是否等于 1。如果不等于则开始执行
  • 您将名为 isFunctionRunning 的数据库字段更新为 1
  • 函数在这里发挥魔力
  • 您将名为 isFunctionRunning 的数据库字段更新为 0

但不知怎的,我认为你想做的事情是“错误的”,可以通过另一种方式实现。如果你说更多细节会有所帮助

编辑:不知道 php 信号量,上面的答案会更快。


0
投票

您可以使用“

flock
”(文件锁定)函数和“
LOCK_EX
”(独占锁)标志来创建一个自定义“同步”函数,该函数接受要同步的处理程序。

您可能会在这里找到代码。

我希望这有帮助。


0
投票

除非 PHP 是单线程的,并且对于所有服务器操作系统(请参阅我的评论),我认为您需要一个两阶段的解决方案。在第 1 阶段,每个进程等待两个锁(lock1 和 lock2)中的每一个都空闲(有超时),然后通过再次检查和设置两个锁来注册其使用资源的愿望。检查是通过将相同的随机数存储到两个锁定文件中来完成的。在第 2 阶段,进程确保它仍然设置了两个锁,然后使用共享资源,然后清除锁。我还没有测试过,但我会尝试一下。

请注意,锁定操作必须暂停通常的 PHP 文件缓存。

© www.soinside.com 2019 - 2024. All rights reserved.