【问题标题】:Removing Semaphore after last sem_release in PHP在 PHP 中的最后一个 sem_release 之后删除信号量
【发布时间】:2012-11-25 23:48:16
【问题描述】:

我在 PHP 中有一个操作,它检查具有 ID 的对象是否在数据库中,如果不是,则为其创建一个条目。同一ID的请求可以同时发生,所以我想防止ID被插入两次。

我目前正在使用以下代码来锁定/解锁对该特定密钥的数据库访问:

$semaphore = sem_get($keyForID, 1);

sem_acquire($semaphore);

// 1.) check for id
// 2.) insert object if it doesn't exist

sem_release($semaphore);

我的问题是: 由于我为每个对象 ID 创建了一个单独的信号量,我是否必须明确地使用 sem_remove 删除这些信号量,或者 PHP 会在 sem_release 之后自动执行此操作吗? ?

如果我必须明确删除信号量,是否有一种简单可靠的方法来检查该信号量当前是否被另一个线程获取,以便后者不会在sem_release 上崩溃?想到使用共享内存,但这需要另一个信号量来读取/写入线程数。

【问题讨论】:

    标签: php multithreading


    【解决方案1】:

    sem_remove 显式销毁给定的信号量,这将使它无法用于任何其他正在运行的进程或线程的进一步计算,直到使用sem_get 重新创建它。例如,如果 3 个进程试图访问同一个信号量(只有 1 个并发访问),并且第一个进程在其他两个进程设法获取它之前将其销毁,则后两个进程可能最终并发运行,而不是顺序运行(正如预期的那样)。

    您真的不想调用sem_remove,除非您知道所有其他正在运行的进程将不再使用它。

    无论如何,在您的情况下,我建议您依靠数据库本身进行并发访问。如果您只需要在数据库中创建一个条目,请使用事务。如果您使用的数据库不支持事务,例如 MySQL 上的 MyISAM 引擎,请切换到支持事务的引擎,或者在 MyISAM 的特定情况下,尝试使用atomic operations

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多