Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erklärung von PHP-Semaphoren

Detaillierte Erklärung von PHP-Semaphoren

*文
*文Original
2017-12-29 18:04:001631Durchsuche

In diesem Artikel wird hauptsächlich die grundlegende Verwendung von PHP-Semaphoren vorgestellt und die grundlegenden Konzepte, Verwendungsfähigkeiten und zugehörigen Vorsichtsmaßnahmen für PHP-Semaphoren ausführlicher analysiert. Ich hoffe, es hilft allen.

Die Details sind wie folgt:

Einige theoretische Grundlagen:

Semaphor: Wird auch als Semaphor und Semaphor bezeichnet Um Prozesse (Thread-Synchronisationsproblem) zu lösen, erwerben Sie ähnlich wie bei einer Sperre die Sperre vor dem Zugriff (warten Sie, wenn sie nicht erworben wird) 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 in denselben Prozess eintreten gleichzeitig Der kritische Bereich einer gemeinsam genutzten Gruppenvariablen, dh ein Prozess greift auf eine kritische Ressource zu und ein anderer 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

Beispiel Beispiel: (von Baidu-Enzyklopädie)

Nehmen Sie als Beispiel den Betrieb eines Parkplatzes. Nehmen Sie der Einfachheit halber an, dass auf dem Parkplatz nur drei Parkplätze vorhanden sind und alle drei Parkplätze zu Beginn leer sind. Wenn zu diesem Zeitpunkt fünf Autos gleichzeitig ankommen, lässt der Pförtner drei von ihnen direkt einfahren und stellt dann den Autoblock auf. Die restlichen Autos müssen am Eingang warten, und nachfolgende Autos müssen ebenfalls warten der Eingang. Zu diesem Zeitpunkt verließ ein Auto den Parkplatz. Nachdem der Pförtner davon erfahren hatte, öffnete er die Autoschranke und stellte das Auto hinein. Wenn noch zwei Autos wegfuhren, konnte er zwei weitere Autos hineinstellen und so weiter.

In diesem Parkplatzsystem sind Parkplätze öffentliche Ressourcen. Jedes Auto ist wie ein Faden und der Pförtner fungiert als Semaphor.


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

Gemeinsamer Speicher + Signal Implementieren Sie atomare Operationen


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

Verwandte Empfehlungen:

Detaillierte Erläuterung der PHP-Shared-Memory-Nutzung

Mehrere gängige Methoden der asynchronen Ausführung von PHP

Konstruktor-Prototyp-Muster von PHP Detaillierte Erklärung des Prototypmusters

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung 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