PHP Doku:: Zugriff auf ein Semaphor anfordern - function.sem-get.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzErweiterungen zur ProzesskontrolleSemaphore, Shared Memory and IPCSemaphore Funktionensem_get

Ein Service von Reinhard Neidl - Webprogrammierung.

Semaphore Funktionen

<<sem_acquire

sem_release>>

sem_get

(PHP 4, PHP 5)

sem_getZugriff auf ein Semaphor anfordern

Beschreibung

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

sem_get() liefert eine ID die für den Zugriff auf das 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.

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 (Vorgabewert ist 1).

perm

Die Zugriffsrechte für den Semaphore. Vorgabewert ist 0777. 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 zrück oder FALSE bei Fehlern.

Changelog

Version Beschreibung
4.3.0 Der auto_release Parameter wurde hinzugefügt.

Siehe auch

  • sem_acquire() - Zugriff auf Semaphor anfordern
  • sem_release() - Semaphor freigeben
  • ftok() - Erzeugt aus einem Dateipfad und einem Projektbezeichner einen System V IPC Schlüssel


7 BenutzerBeiträge:
- Beiträge aktualisieren...
pail dot luo at gmail dot com
27.02.2009 3:40
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);
?>
cyrus dot drive at gmail dot com
2.05.2008 2:51
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); }
   
}
?>
quickshiftin at gmail dot com
31.07.2007 5:55
in regards to the last post, it looks like there is a mistake.
well, understandably, the documentation isnt quite clear on a point the post uses to rationalize its claim, allow me to explain.
the purpose of a semaphore is to manage access to a shared resource, so natrually it follows that if multiple attempts to access the same semaphore arent blocking (when expected to), then the api simply isnt being used properly.

the problem is that the documentation does not stipulate what will happen if the max_acquire paramter is varied upon successive invocations of the sem_get method.  so setting it to 100, then to 1 on 2 successive calls will have an undefined behavior.  if the value is kept constant however (and set to 1 for the example), you will find, as i did that the second attempt to acquire the semaphore will block.  NOTE: this does not work when using
php -a

here is the revised sample code:
<?php
$fp1
= sem_get(fileinode('commonResource'), 1);

sem_acquire($fp1);
echo
'got mutex' . PHP_EOL;

$fp2 = sem_get(fileinode('commonResource'), 1);
sem_acquire($fp2);
echo
'got mutex again' . PHP_EOL;
?>

note there are 2 references; $fp1 and $fp2 and you will not see the second message because the script will block forever.
ein at anti-logic dot com
26.06.2007 13:21
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.
neofutur
28.08.2006 21:49
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/
joeldg AT listbid.com
2.05.2003 20:39
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);
joeldg at listbid.com
2.05.2003 9:36
<?
// 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);
?>



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)