PHP no wait sem_acquire?

2019-06-25 09:19发布

问题:

Not a specific code question, but more of a general coding question. I'm trying to use a semaphore in a work project to limit the number of users that can access certain processes at a concurrent time.

From my understanding the following:

$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);
    }
}

The problem that I see here is that if there is already one user who has the semaphore key, then the next user just waits until the first user is done rather than just faulting out. Anyone know of a way that if the max_acquire number has been reached, sem_acquire (or similar) will just return false?

Thanks

回答1:

Nope, it's not possible according to the implementation used by PHP.

According to the semop() man page, it should be able to take the IPC_NOWAIT flag somewhere, but it doesn't look like the PHP implementation does.

Actually, looking at the PHP source code for the sysvsem package, you can clearly see that it will continue blocking even if signals interrupt the blocked process (line 320). While this might not be optimal, it's fine as long as you understand the limitations.

As far as your use case, there may be other implementations (such as a file lock against a memory filesystem) that would be just as good for most usecases and have the ability to do exactly what you need...



回答2:

Starting from PHP 5.6.1, it supports the $nowait parameter for sem_acquire:

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

By the way, the second parameter to ftok() in PHP must be a one character string, not the string consisting of multiple characters, as in your case. For example

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


标签: php semaphore