PHP中的同步函数

PHP中的同步函数,php,Php,有没有办法使PHP中的函数同步,以确保两个或多个Web用户不能同时执行同一个函数?我想不出您可能会遇到什么问题。然而,我曾经不得不编写一个PHP脚本来进行一些复杂的计算,我必须确保它不是由两个用户同时执行的。为了实现这一点,我在脚本开始时创建了一个空文件,并在计算完成后将其删除。当然,脚本在开始计算之前检查了文件是否存在。我认为,通过使用获取信号量(进入crital部分)和释放锁,您可能会实现相同的效果(如果可用)。您可以使用外部锁定-例如,通过。在某处创建一个文件并让脚本锁定它。您也可以使用,

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

我想不出您可能会遇到什么问题。然而,我曾经不得不编写一个PHP脚本来进行一些复杂的计算,我必须确保它不是由两个用户同时执行的。为了实现这一点,我在脚本开始时创建了一个空文件,并在计算完成后将其删除。当然,脚本在开始计算之前检查了文件是否存在。

我认为,通过使用获取信号量(进入crital部分)和释放锁,您可能会实现相同的效果(如果可用)。

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

请注意,只有当您有一台web服务器时,本地文件锁定和信号量才起作用。如果脚本由多个负载平衡服务器托管,则必须找到其他锁定机制,例如一台机器上的专用“锁定服务器”或NFS上的某种文件锁定。

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


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

有关为什么需要锁定的更多详细信息。如果您在用户的数据库交互相互碰撞方面遇到问题,那么您应该考虑在数据库代码中使用事务,以便数据库以原子方式处理复杂的更改

例如:我将Symfony与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的更改进行大杂烩。

我认为您需要在这里提供更多的信息。你想执行的函数不是线程安全的吗?这个线程有点老了,但是我认为这是一个很好的答案:数据库可能更快,考虑一下。考虑一下:Prcess 1 CECKS文件存在并且不存在。然后进程1的时间段结束,轮到进程2检查文件是否存在,因为进程2尚未创建文件。两个进程将在同一时间运行!您的解决方案可以降低风险,但不能消除风险。你应该像阿尔弗雷德建议的那样使用sem_-aquire。@Oliver A:请记住,我很久以前才描述过我使用的解决方案。我没说这是最好的,巴拉恩。我从未打算攻击/侮辱你。我只是想指出,这并不像听起来那么简单。默认情况下,sem_acquire和sem_release不可用,而且在Windows上也不可用。我喜欢这个答案。是“群集”方法的一个示例。