Heim  >  Artikel  >  Backend-Entwicklung  >  Verwendung und Beispiele von PHP-Semaphoren

Verwendung und Beispiele von PHP-Semaphoren

墨辰丷
墨辰丷Original
2018-06-05 11:08:421968Durchsuche

In diesem Artikel werden hauptsächlich die Verwendung und Beispiele von PHP-Semaphoren vorgestellt. Ich hoffe, dass er für alle hilfreich ist.

Theoretische Basis:

Semaphor : auch bekannt als Semaphor und Semaphor Prozess (Thread-Synchronisationsproblem), ähnlich einer Sperre, erwerben Sie die Sperre vor dem Zugriff (warten Sie, wenn sie nicht erworben wurde) und geben Sie die Sperre nach dem Zugriff frei.
Kritische Ressourcen : Ressourcen, auf die jeweils nur ein Prozess zugreifen darf.
Kritischer Abschnitt: Der Code, der in jedem Prozess auf kritische Ressourcen zugreift, wird als kritischer Abschnitt bezeichnet
Gegenseitiger Prozessausschluss : Zwei oder mehr Prozesse können nicht gleichzeitig den kritischen Bereich auf demselben Satz gemeinsam genutzter Variablen betreten, dh ein Prozess greift auf kritische Ressourcen zu und der andere Prozess muss warten, bevor er darauf zugreift.
ProzesssynchronisationUntersucht hauptsächlich, wie man die Ausführungsreihenfolge zwischen mehreren Prozessen bestimmt und Datenkonkurrenzprobleme vermeidet, d. h. wie man dafür sorgt, dass mehrere Prozesse gut zusammenlaufen

Das Beispiel sieht wie folgt aus:

$key=ftok(__FILE__,'t');
/**
 * 获取一个信号量资源
 int $key [, int $max_acquire = 1 [, int $perm = 0666 [, int $auto_release = 1 ]]] 
 $max_acquire:最多可以多少个进程同时获取信号
 $perm:权限 默认 0666
 $auto_release:是否自动释放信号量
 */
$sem_id=sem_get($key);
#获取信号
sem_acquire($seg_id);
//do something 这里是一个原子性操作
//释放信号量
sem_release($seg_id);
//把次信号从系统中移除
sem_remove($sem_id);
//可能出现的问题
$fp = sem_get(fileinode(__DIR__), 100);
sem_acquire($fp);
$fp2 = sem_get(fileinode(__DIR__), 1));
sem_acquire($fp2);

Implementierung eines Lese-Schreib-Semaphors in 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); }
}

Shared Memory+ Signale implementieren Atomoperationen

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

Zusammenfassung: Das Obige ist der gesamte Inhalt dieses Artikels, ich hoffe, er wird für das Lernen aller hilfreich sein.

Verwandte Empfehlungen:

So implementieren Sie die Anzeigefunktion für Datenseiten in PHP

PHP-gekapselte MSSql-Operationsklasse und vollständige Beispielanalyse

PHP-Methode zur Verbindung mit der Oracle-Datenbank und einfache Analyse

Das obige ist der detaillierte Inhalt vonVerwendung und Beispiele von PHP-Semaphoren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn