PHP не ждать sem_acquire? - PullRequest
       15

PHP не ждать sem_acquire?

4 голосов
/ 01 февраля 2011

Не конкретный кодовый вопрос, а скорее общий вопрос кодирования. Я пытаюсь использовать семафор в рабочем проекте, чтобы ограничить число пользователей, которые могут одновременно получать доступ к определенным процессам.

Из моего понимания следующее:

$iKey = ftock($sSomeFileLocation,'sOneCharacterString'); //Generate the key
if($sem_id = sem_get($iKey)){                            //1 user allowed
    if(sem_acquire($sem_id)){
        //Do the limited process here
        sem_release($sem_id);
    }
}

Проблема, которую я вижу здесь, состоит в том, что если уже есть один пользователь, имеющий ключ семафора, то следующий пользователь просто ждет, пока первый пользователь не завершит работу, а не просто выйдет из строя. Кто-нибудь знает способ, которым, если число max_acquire было достигнуто, sem_acquire (или подобное) просто вернет false?

Спасибо

Ответы [ 2 ]

3 голосов
/ 01 февраля 2011

Нет, это невозможно в соответствии с реализацией, используемой PHP.

Согласно справочной странице semop() , он должен иметь возможность где-то взять флаг IPC_NOWAIT, но это не похоже на реализацию PHP.

На самом деле, глядя на исходный код PHP для пакета sysvsem , вы можете ясно увидеть, что он продолжит блокировку, даже если сигналы прерывают заблокированный процесс (строка 320). Хотя это может быть неоптимально, но это нормально, если вы понимаете ограничения.

Что касается вашего варианта использования, то могут быть и другие реализации (например, блокировка файла для файловой системы памяти), которые были бы столь же хороши для большинства случаев использования и могли бы делать именно то, что вам нужно ...

1 голос
/ 22 апреля 2017

Начиная с PHP 5.6.1, он поддерживает параметр $ nowait для sem_acquire:

bool sem_acquire ( resource $sem_identifier [, bool $nowait = false ] )

Кстати, вторым параметром ftok () в PHP должна быть строка из одного символа, а не строка, состоящая из нескольких символов, как в вашем случае. Например

$project = "c";
$key = ftok(__FILE__, $project);
...