English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Base de la communication de processus PHP via les semaphores et la mémoire partagée

Since it is not certain which process will execute first between processes, it depends on the complex process scheduling algorithm of the kernel. Therefore, it is possible for multiple processes to access shared memory at the same time, causing unpredictable errors. The name 'semaphore' is very mysterious, but it is very easy to understand when you look at its English meaning.

semaphore 英[ˈseməfɔ:(r)] vt. Send signal, signal with flags;

Similar to the role of a commander.

Let's look at the next pseudo-code for semaphore usage.

1Create unique semaphore identifier

$ftok = ftok(__FILE__, 'a');

2Create semaphore resource ID

$sem_resouce_id = sem_get($ftok);

3Acquire semaphore

sem_acqure($sem_resource_id);

4Release semaphore

sem_release($sem_resource_id);

5Destroy semaphore

sem_remove($sem_resource_id);

Let's take an unrefined example to make it easy to understand the use of semaphores in everyday life. After understanding, it can be applied to our programming field.
A company has only one toilet. When someone is using the toilet, they need to acquire a lock (semaphore) to indicate that the toilet is in use. The code is as follows:

sem_acqure($sem_resource_id);

After the staff have finished using the toilet, the lock needs to be opened and the lock (semaphore) released to indicate that others can now use it. The code is as follows:

sem_release($sem_resource_id);

With a simple lock, we can know whether the current toilet (shared memory) is available. This example is not elegant, but it illustrates the problem. This blog also has a taste, it's not easy to write......The following is an example of code:

<?php
//Create shared memory area
$shm_key = ftok(__FILE__, 'a');
$shm_id = shm_attach($shm_key, 1024, 0755);
//var_dump($shm_id);die(); resource(4) of type (sysvshm)
const SHARE_KEY = 1;
$child_list = [];
//Join semaphore
$sem_id = ftok(__FILE__, 'b');
$signal = sem_get($sem_id);
//$signal resource(5) of type (sysvsem)
for ($i = 0; $i < 3; $i++) {
  $pid = pcntl_fork();
  exit("Fork fail!".PHP_EOL); -1) {
    elseif ($pid == 0) {
  }
    //Obtenir le sémaphore
    sem_acquire($signal);
    if (shm_has_var($shm_id,SHARE_KEY)) {
      $count = shm_get_var($shm_id, SHARE_KEY);
      $count++;
      //Simuler le traitement des affaires
      $sec = rand(1, 3);
      sleep($sec);
      shm_put_var($shm_id, SHARE_KEY, $count);
    }
      $count = 0;
      $sec = rand(1, 3);
      sleep($sec);
      shm_put_var($shm_id, SHARE_KEY, $count);
    }
    echo "child process: ".getmypid()." is writing! now count is: $count ".PHP_EOL;
    //Libérer le sémaphore
    sem_release($signal);
    exit("child process".getmypid()."end".PHP_EOL);
  }
    $child_list[] = $pid;
  }
}
while (count($child_list) > 0) {
  foreach ($child_list as $key => $pid) {
    $status = pcntl_waitpid($pid, $status);
    if ($status > 0 || $status == -1) {
      unset($child_list[$key]);
    }
  }
  sleep(1);
}
$count = shm_get_var($shm_id, SHARE_KEY);
echo " $count  ".PHP_EOL;
//Détruire le sémaphore
sem_remove($signal);
shm_remove($shm_id);
shm_detach($shm_id);
Vous pourriez aussi aimer