An Example Analysis of PHP Shared Memory Usage and Signal Control

  • 2021-10-11 17:45:38
  • OfStack

This paper describes the use of PHP shared memory and signal control. Share it for your reference, as follows:

Shared memory

Shared memory is mainly used to share data among different processes on the same machine, such as sharing the current process usage among multiple php-fpm processes. This communication is also called inter-process communication (Inter-Process Communication), or IPC for short.

PHP built-in shmop extension (Shared Memory Operations) provides a series of shared memory operation functions (maybe not many people use it, this one piece of document has not been translated in Chinese). On Linux, these functions are implemented directly by calling shm* family functions, while on Winodows, the same call is realized by encapsulating system functions.

Main functions:

shmop_close-Close shared memory block

shmop_delete-Deleting shared memory blocks

shmop_open-Create or open a shared memory block

shmop_read-Reading data from a shared memory block

shmop_size--Gets the size of the shared memory block

shmop_write-Writing data to a shared memory block

Also related to this is a very important function: ftok, which creates the only 1 key of IPC (the inode of files/folders is only 1) from the inode information of files (viewed through stat or ls-i command on * nix). This function in Linux is also a direct call to the system function implementation of the same name, Windows or use some encapsulation.

A simple counting example:


<?php
#  Create 1 Block shared memory 
$shm_key = ftok(__FILE__, 't');
$shm_id = shmop_open($shm_key, 'c', 0644, 8);
#  Read and write data 
$count = (int) shmop_read($shm_id, 0, 8) + 1;
shmop_write($shm_id, str_pad($count, 8, '0', STR_PAD_LEFT), 0);
// echo shmop_read($shm_id, 0, 8);
#  Closing the memory block does not delete the shared memory, but only clears the  PHP  Resources of 
shmop_close($shm_id);

The above code does not perform 1 count plus 1, and the data is shared between different processes. This means that this data will not be reset unless this memory usage is manually deleted.

There is a point that needs a little attention: the second parameter of shmop_open is an flag, similar to the second parameter of fopen, and its values are the previous ones:

"a" read-only access;

"c" If the memory fragment does not exist, it is created, and if it exists, it can be read and written;

"w" reading and writing;

"n" creates a new memory fragment that fails if the same key already exists, for the safe use of shared memory.

In addition, because the shared memory fragment used is of fixed length, the length of the data should be calculated when storing and reading, otherwise the write may fail or the null value may be read.

Signal control

Since shared memory is used to store data above, it is necessary to consider whether multiple processes write data to shared memory at the same time and whether conflicts need to be avoided. If this is the case, semaphores need to be introduced for control.

PHP also provides a similar built-in extension, sysvsem (this extension is not available in the Windows environment, and the ftok function is also included in this extension in the document, but ftok is actually provided in the standard function library, so it is also available under Windows).

Before talking about semaphore control, let's say another interesting thing: Look at the official documents and you will find that there are also shared memory operation functions (shm_*), because these are actually three extensions of the same category (or from the same author), and one is sysvmsg (queue message). The implementation of the function is slightly different, but the actual things are basically the same. How does this differ from the shmop extension above? shmop source code under the README file has a simple description:

PHP already had a shared memory extension (sysvshm) written by Christian Cartus < cartus@atrior.de > , unfortunately this extension was designed with PHP only in mind and offers high level features which are extremely bothersome for basic SHM we had in mind.

Simply put, the sysvshm extension does not provide the method of storing the user's data intact, but serializes the parameters before storing them using the variable serialization function of PHP. This results in data stored through these methods not being shared with non-PHP processes. However, this can also store a richer PHP data type, and shmop_write in the above extension can only write strings. So why does sysvshm also not support Windows? Because it does not introduce the tsrm_win32.h header file that encapsulates the shm* family of functions.

Example after introducing signal control:


<?php
$id_key = ftok(__FILE__, 't');
$sem_id = sem_get($id_key);
#  Request signal control 
if (sem_acquire($sem_id)) {
  $shm_id = shmop_open($id_key, 'c', 0644, 8);
  #  Read and write data 
  $count = (int) shmop_read($shm_id, 0, 8) + 1;
  shmop_write($shm_id, str_pad($count, 8, '0', STR_PAD_LEFT), 0);
  // echo shmop_read($shm_id, 0, 8);
  #  Close the memory block 
  shmop_close($shm_id);
  #  Release signal 
  sem_release($sem_id);
}

However, it is actually very difficult to simulate and implement write conflicts locally (considering the execution speed of the computer). In local tests, when using an for loop operation to close a resource without using shmop_close, an error warning that shared memory cannot be opened appears. This should be because the shared memory was occupied by the last operation and has not been released.

For more readers interested in PHP related content, please check the topics on this site: "Introduction to PHP Basic Syntax", "Summary of PHP Error and Exception Handling Methods", "Summary of php Programming Algorithms" and "Introduction to php Object-Oriented Programming"

I hope this paper is helpful to everyone's PHP programming.


Related articles: