семафор — PHP sem_get не работает

Я реализовал контроль доступа для вставок в таблицу базы данных, которая используется для службы бронирования. Некоторое время работает нормально, потом 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;

Я должен звонить sem_remove() также?

Я следовал за шагами на этот сайт.

3

Решение

Удаление семафоров

Да, тебе следует позвонить sem_remove() когда вы закончите с набором семафоров. В противном случае набор семафоров будет сохраняться в системе до тех пор, пока вы его не удалите. Однако тот факт, что набор семафоров сохраняется, вызывает нет проблем в то время как число семафоров меньше, чем SEMMNS предел:

SEMMNS Общесистемное ограничение на количество семафоров: зависит от политики (в Linux это ограничение можно прочитать и изменить с помощью второго поля /proc/sys/kernel/sem).

sem_remove() немедленно удаляет набор семафоров, пробуждая все процессы, заблокированные этим семафором.

Кстати, вы можете использовать ipcrm команда для удаления семафоров из командной строки, и ipcs команда для отображения информации об объектах IPC (включая семафоры).

Выпуск семафоров

Вы не обязаны звонить sem_release() пока флаг авто-релиза (sem_get4-й параметр) включен. Но это хорошая идея — выпускать семафоры, если вам не нужен приобретенный «замок».

sem_release() только увеличивает значение внутреннего семафора. Думайте об этом как об операции разблокировки, противоположной sem_acquire(),

sem_get() Отказы

sem_get() функция возвращает FALSE в следующих случаях

  • Ошибка разбора параметра PHP (E_ERROR);
  • семафор существует, но вызывающий процесс не имеет разрешения на доступ к набору (E_WARNING);
  • ошибка выделения памяти (E_WARNING);
  • максимальное количество наборов семафоров или максимальное системное число семафоров превышает (E_WARNING)

В каждом из случаев sem_get регистрирует ошибку или предупреждение. Так что вы должны проверить журналы для того, чтобы узнать корень проблемы.

Поскольку ваш код работает в течение некоторого времени, это не проблема разбора параметров и не разрешения. Проблемы с выделением памяти редки. Таким образом, очень вероятно, что вы исчерпали пределы числа семафоров. Проверьте справочную страницу для semget для справки. Страница man описывает, как читать и изменять ограничения с помощью /proc/sys/kernel/sem,

Ссылаться на этот Ответьте для получения дополнительной информации относительно sysvsem внутреннее расширение.

0

Другие решения

Аргумент $ key для sem_get () является целочисленным, в то время как вы передаете его как строку. Пожалуйста, рассмотрите возможность получения целочисленного ключа с помощью вызова ftok ().

Поэтому, пожалуйста, подумайте о замене

$key = "room";

к следующему коду:

$project = "r"; // Project identifier. This must be a one character string.
$key = ftok(__FILE__, $project);
0

По вопросам рекламы [email protected]