PHP sem_get 函数失败

Jok*_*Dev 5 php semaphore sysv-ipc

我已经实现了一个用于插入到用于预订服务的数据库表中的访问控制。它可以正常工作一段时间,然后sem_get()尽管我sem_release()在每个sem_get().

case 'room':
    $key = "room";
    $semaphore = sem_get($key, 1, 0666, 1);
    if ($semaphore) {
        sem_acquire($semaphore);
        //do some stuff
        if ($already_reserved_rooms < $max_rooms) {
            $return="ok";
            sem_release($semaphore);
            return $return;
        }
          sem_release($semaphore);
    }
    else {
      //send me mail that semaphore failed 
    }

    return 'no rooms';
    break;
Run Code Online (Sandbox Code Playgroud)

sem_remove()也应该打电话吗?

我按照这个网站上的步骤。

Rus*_*nov 3

删除信号量

sem_remove()是的,您应该在完成信号量设置后调用。否则,信号量集将保留在系统中,直到您将其删除。然而,当信号量的数量小于限制时,信号量集持续存在的事实不会导致问题SEMMNS

SEMMNS系统范围内的信号量数量限制:取决于策略(在 Linux 上,可以通过 的第二个字段读取和修改此限制 /proc/sys/kernel/sem)。

sem_remove()立即删除信号量集,唤醒使用该信号量阻塞的所有进程。

顺便说一句,您可以使用该ipcrm命令从命令行中删除信号量,以及使用该ipcs命令显示有关IPC设施(包括信号量)的信息。

释放信号量

sem_release()当自动释放标志(sem_get的第四个参数)打开时,您不需要调用。但只要不需要获取的“锁”,释放信号量就是一个好主意。

sem_release()仅增加内部信号量的值。将其视为解锁操作,与sem_acquire().

sem_get()失败

该函数在以下情况下sem_get()返回FALSE

  • PHP参数解析失败( E_ERROR);
  • 信号量存在,但调用进程无权访问set( E_WARNING);
  • 内存分配错误(E_WARNING);
  • 信号量集的最大数量,或系统范围的最大信号量数量超过 ( E_WARNING)

在每种情况下sem_get都会记录一个错误或警告。因此,您必须检查日志才能找出问题的根源。

由于您的代码可以运行一段时间,因此这不是参数解析问题,也不是权限问题。内存分配问题很少见。因此,您很可能会超出信号量数量限制。查看手册页以供semget参考。手册页描述了如何通过 读取和修改限制/proc/sys/kernel/sem

有关扩展内部结构的更多信息,请参阅sysvsem答案。