sem_get

(PHP 4, PHP 5)

sem_getObtener el id de un semáforo

Descripción

resource sem_get ( int $key [, int $max_acquire = 1 [, int $perm = 0666 [, int $auto_release = 1 ]]] )

sem_get() devuelve un id que se puede usar para acceder al semáforo de System V con la clave dada por key.

Una segunda llamada a sem_get() para la misma clave devolverá un identificador de semáforo diferente, pero ambos identificadores accederán al mismo semáforo subyacente.

Parámetros

key

max_acquire

El número de procesos que puede adquirir el semáforo simultáneamente está establecido por max_acquire.

perm

Los permisos del semáforo. En realidad este valor se establece sólo si el proceso que lo encuentra es el único proceso actualmente adjunto al semáforo.

auto_release

Especifica si el semáforo debería ser liberado automáticamente al cierre de la petición.

Valores devueltos

Devuelve un identificador de semáforo positivo en caso de éxito, o FALSE en caso de error.

Notas

Advertencia

Al usar sem_get() para acceder a un semáforo creado fuera de PHP, se ha de observar que el semáforo debe haber sido creado como un conjunto de 3 semáforos (por ejemplo, especificando 3 en el parámetro nsems, al llamar a la función semget() de C), de lo contrario, PHP no podrá acceder al semáforo.

Ver también

  • sem_acquire() - Adquirir un semáforo
  • sem_release() - Liberar un semáforo
  • ftok() - Convertir un nombre de ruta y un identificador de proyecto a una clave IPC de System V

add a note add a note

User Contributed Notes 8 notes

up
4
soger
3 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
0
Michael Z.
3 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
0
ein at anti-logic dot com
7 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.
up
0
neofutur
8 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
11 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
0
joeldg at listbid.com
11 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
cyrus dot drive at gmail dot com
6 years ago
Implementation of a read-write semaphore in PHP:

<?php
class rw_semaphore {
       
    const
READ_ACCESS = 0;
    const
WRITE_ACCESS = 1;   
   
   
/**
     * @access private
     * @var resource - mutex semaphore
     */
   
private $mutex;
   
   
/**
     * @access private
     * @var resource - read/write semaphore
     */
   
private $resource;
   
   
/**
     * @access private
     * @var int
     */
   
private $writers = 0;
   
   
/**
     * @access private
     * @var int
     */
   
private $readers = 0;

   
/**
     * Default constructor
     *
     * Initialize the read/write semaphore
     */
   
public function __construct() {
       
$mutex_key = ftok('/home/cyrus/development/php/sysvipc/rw_semaphore.php', 'm');
       
$resource_key = ftok('/home/cyrus/development/php/sysvipc/rw_semaphore.php', 'r');       
       
$this->mutex = sem_get($mutex_key, 1);
       
$this->resource = sem_get($resource_key, 1);       
    }
   
   
/**
     * Destructor
     *
     * Remove the read/write semaphore
     */
   
public function __destruct() {
       
sem_remove($this->mutex);
       
sem_remove($this->resource);
    }
   
   
/**
     * Request acess to the resource
     *
     * @param int $mode
     * @return void
     */
   
private function request_access($access_type = self::READ_ACCESS) {   
        if (
$access_type == self::WRITE_ACCESS) {
           
sem_acquire($this->mutex);
           
           
/* update the writers counter */
           
$this->writers++;
           
           
sem_release($this->mutex);           
           
sem_acquire($this->resource);
        } else {           
           
sem_acquire($this->mutex);           
            if (
$this->writers > 0 || $this->readers == 0) {               
               
sem_release($this->mutex);               
               
sem_acquire($this->resource);               
               
sem_acquire($this->mutex);               
            }
           
/* update the readers counter */
           
$this->readers++;
           
           
sem_release($this->mutex);
        }
    }
   
    private function
request_release($access_type = self::READ_ACCESS) {
        if (
$access_type == self::WRITE_ACCESS) {
           
sem_acquire($this->mutex);
           
           
/* update the writers counter */
           
$this->writers--;
           
           
sem_release($this->mutex);
           
sem_release($this->resource);
        } else {
           
sem_acquire($this->mutex);
           
           
/* update the readers counter */
           
$this->readers--;
           
            if (
$this->readers == 0)
               
sem_release($this->resource);
           
           
sem_release($this->mutex);
        }
    }
   
   
/**
     * Request read access to the resource
     *
     * @return void
     */
   
public function read_access() { $this->request_access(self::READ_ACCESS); }
   
   
/**
     * Release read access to the resource
     *
     * @return void
     */
   
public function read_release() { $this->request_release(self::READ_ACCESS); }
   
   
/**
     * Request write access to the resource
     *
     * @return void
     */
   
public function write_access() { $this->request_access(self::WRITE_ACCESS); }
   
   
/**
     * Release write access to the resource
     *
     * @return void
     */
   
public function write_release() { $this->request_release(self::WRITE_ACCESS); }
   
}
?>
up
-3
pail dot luo at gmail dot com
5 years ago
A very simple to introduce semaphore...

<?php
$SEMKey
= "123456" ;

## Get Semaphore id
$seg = sem_get( $SEMKey, 2, 0666, -1) ;

if (
$argv[1]=="remove" ) {
   
sem_remove($seg);
}

echo
"Try to acquire ..."
sem_acquire($seg);
echo
"Acquired...\n" ;

echo
"Press Any Key to continue...\n";
$fh = fopen("php://stdin", "r");
$a = fgets( $fh);
fclose($fh);

sem_release($seg);
?>
To Top