PHP 8.4.0 RC4 available for testing

sem_get

(PHP 4, PHP 5, PHP 7, PHP 8)

sem_getFordert Zugriff auf eine Semaphor-ID an

Beschreibung

sem_get(
    int $key,
    int $max_acquire = 1,
    int $permissions = 0666,
    bool $auto_release = true
): SysvSemaphore|false

sem_get() liefert eine ID, die für den Zugriff auf den System-V-Semaphor mit dem gegebenen key benutzt werden kann.

Weitere Aufrufe von sem_get() für den gleichen Key liefern unterschiedliche Semaphor-IDs, diese greifen aber auf den gleichen darunterliegenden Semaphor zu.

Ist key gleich 0 wird ein neuer privater Semaphor für jeden Aufruf von sem_get() erzeugt.

Parameter-Liste

key

max_acquire

Die Anzahl der Prozesse, die gleichzeitig Zugriff auf den Semaphor erhalten können, wird durch den Parameter max_acquire festgelegt

permissions

Die Zugriffsrechte für den Semaphore. Der Wert wird nur gesetzt, wenn der aktuelle Prozess der einzige ist der in diesem Augenblick mit dem Semaphor verknüpft ist.

auto_release

Legt fest, ob der Semaphor am Skriptende automatisch freigegeben werden soll.

Rückgabewerte

Gibt einen positiven Semaphor-Identifier zurück oder false bei Fehlern.

Changelog

Version Beschreibung
8.0.0 Bei Erfolg gibt diese Funktion nun eine SysvSemaphore-Instanz zurück; vorher wurde eine resource zurückgegeben.
8.0.0 Der Typ von auto_release wurde von int auf bool geändert.

Anmerkungen

Warnung

Wird sem_get() verwendet, um auf einen Semaphor zuzugreifen, der außerhalb von PHP erzeugt wurde, ist zu beachten, dass der Semaphor als ein Satz von 3 Semaphoren erzeugt wurde (zum Beispiel durch Angabe von 3 für den nsems-Parameter beim Aufruf der C-Funktion semget()); andernfalls wird PHP nicht in der Lage sein, auf den Semaphor zuzugreifen.

Siehe auch

  • sem_acquire() - Fordert Zugriff auf einen Semaphor an
  • sem_release() - Gibt einen Semaphor frei
  • ftok() - Erzeugt aus einem Dateipfad und einem Projektbezeichner einen System-V-IPC-Schlüssel

add a note

User Contributed Notes 9 notes

up
3
Dan East
3 years ago
Note that the default permissions parameter is octal! Thus the default of 0666 is NOT the same as 666, or 0x666.

If you specify the permission as decimal 666 then you end up with permissions that prevent the semaphore from being read. The symptom is that you can only sem_get it once, and subsequent sem_get will fail (until you ipcrm or sem_remove it and delete it entirely).

Thus these are all equivalent to the default:
sem_get ( 123, 1, 0666)
sem_get ( 123, 1, 438)
sem_get ( 123, 1, 0x1b6)

Most PHP developers (myself included) work with octal numbers so infrequently that the number 0666 can easily be mistaken as 666 or maybe 0x666.
up
12
soger
13 years ago
Actually it looks like the semaphore is automatically released not on request shutdown but when the variable you store it's resource ID is freed. That is a very big difference.
up
6
kakkau at grr dot la
8 years ago
It is possible to create an "infinite" amount of semaphores when setting $key = 0.

Run sem_get multiple times
php > sem_get(0,0);

and check the output of
$ ipcs -s

------ Semaphore Arrays --------
key semid owner perms nsems
0x00000000 1277952 user 666 3
0x00000000 1310721 user 666 3

As you can see there were multiple semaphores set up with key 0.
For any other integer sem_get works as expected. It returns another resource id pointing to the semaphore previously created and does not create another semaphore.
up
1
kakkau at grr dot la
9 years ago
For those that encounter strange behavior in using sem_acquire() on resources generated by sem_get(). Have a look at sem_get()'s 4th parameter auto_release. It allows multiple acquisitions through reassignments to resource variables.

./multi.acquire.php
<?php
class Sem {
private
$key = null;
private
$res = null;
public function
__construct() {
$this->key = ftok(".",".");
$this->set_res();
$this->acquire();
}
public function
set_res() {
// 4th parameter auto_released is 1 by default
$this->res = sem_get($this->key, 1, 0600, 1);
}
public function
acquire() {
echo
"acquired='".sem_acquire($this->res,true)."'\n";
}
}

$s = new Sem();
$s->set_res();
$s->acquire();

?>

$ php multi.acquire.php
acquired='1'
acquired='1'

To avoid reacquiring by default set sem_get()'s parameter auto_release to 0 or check if your resource variable is already set, e.g. by using is_null().
up
1
Michael Z.
13 years ago
Watch out when you use fileinode() to get a unique semaphore key (as suggested in some comment on this or a related function) in conjunction with version control software: It seems, for example, SVN will change the inode. Using such a file will leave you with your mutex not working reliably and your system's semaphore pool being filled until further attempts to get a semaphore will fail. Use ipcs and ipcrm commands from linux-util-ng (on most distros probably) to examine/fix related problems.
up
1
neofutur
18 years ago
with gentoo php5 you will need to add the USE flag :
sysvipc

see :
http://forums.gentoo.org/viewtopic-t-464175-highlight-semget+php.html

and also :
http://overlays.gentoo.org/proj/php/
up
0
joeldg at listbid.com
21 years ago
<?
// thanks to
// http://www.ecst.csuchico.edu/~beej/guide/ipc/shmem.html
$SHM_KEY = ftok("/home/joeldg/homeymail/shmtest.php", 'R');
$shmid = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$data = shm_attach($shmid, 1024);

$data = "test";
printf("shared contents: %s\n", $data);

shm_detach($data);
?>
up
-1
joeldg AT listbid.com
21 years ago
Heh, actually the above comment I added is not technically correct, it was more of an idea to display the function.

$SHM_KEY = ftok("/home/joeldg/homeymail/shmtest.php", 'R');
$shmid = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$data = shm_attach($shmid, 1024);
// we now have our shm segment

// lets place a variable in there
shm_put_var ($data, $inmem, "test");
// now lets get it back. we could be in a forked process and still have
// access to this variable.
printf("shared contents: %s\n", shm_get_var($data, $inmem));

shm_detach($data);
up
-4
ein at anti-logic dot com
17 years ago
Be aware that there is no way to ensure that you have exclusive access to a lock, despite setting max_acquire=1.

In example,
<?
$fp = sem_get(fileinode('lock_file', 100);
sem_acquire($fp);

$fp2 = sem_get(fileinode('lock_file', 1);
sem_acquire($fp2);
?>

This will not block on the second sem_aquire. Therefore, if you have functions or processes that utilize shared locks (>1 max_acquire) you will still need to provide a seperate lock mechanism (ie flock) for write access, making the sem_ functions useless.

Some more info, in flock, each reference to the lock file has it's own options (can be shared exclusive blocking non blocking etc), but apparently php's sem functions only support these options per semaphore, not per semaphore-reference.
To Top