Я реализовал контроль доступа для вставок в таблицу базы данных, которая используется для службы бронирования. Некоторое время работает нормально, потом 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()
также?
Я следовал за шагами на этот сайт.
Удаление семафоров
Да, тебе следует позвонить sem_remove()
когда вы закончите с набором семафоров. В противном случае набор семафоров будет сохраняться в системе до тех пор, пока вы его не удалите. Однако тот факт, что набор семафоров сохраняется, вызывает нет проблем в то время как число семафоров меньше, чем SEMMNS
предел:
SEMMNS
Общесистемное ограничение на количество семафоров: зависит от политики (в Linux это ограничение можно прочитать и изменить с помощью второго поля/proc/sys/kernel/sem
).
sem_remove()
немедленно удаляет набор семафоров, пробуждая все процессы, заблокированные этим семафором.
Кстати, вы можете использовать ipcrm
команда для удаления семафоров из командной строки, и ipcs
команда для отображения информации об объектах IPC (включая семафоры).
Выпуск семафоров
Вы не обязаны звонить sem_release()
пока флаг авто-релиза (sem_get
4-й параметр) включен. Но это хорошая идея — выпускать семафоры, если вам не нужен приобретенный «замок».
sem_release()
только увеличивает значение внутреннего семафора. Думайте об этом как об операции разблокировки, противоположной sem_acquire()
,
sem_get()
Отказы
sem_get()
функция возвращает FALSE
в следующих случаях
E_ERROR
);E_WARNING
);E_WARNING
);E_WARNING
)В каждом из случаев sem_get
регистрирует ошибку или предупреждение. Так что вы должны проверить журналы для того, чтобы узнать корень проблемы.
Поскольку ваш код работает в течение некоторого времени, это не проблема разбора параметров и не разрешения. Проблемы с выделением памяти редки. Таким образом, очень вероятно, что вы исчерпали пределы числа семафоров. Проверьте справочную страницу для semget
для справки. Страница man описывает, как читать и изменять ограничения с помощью /proc/sys/kernel/sem
,
Ссылаться на этот Ответьте для получения дополнительной информации относительно sysvsem
внутреннее расширение.
Аргумент $ key для sem_get () является целочисленным, в то время как вы передаете его как строку. Пожалуйста, рассмотрите возможность получения целочисленного ключа с помощью вызова ftok ().
Поэтому, пожалуйста, подумайте о замене
$key = "room";
к следующему коду:
$project = "r"; // Project identifier. This must be a one character string.
$key = ftok(__FILE__, $project);