If developers want to enable the PHP process to read and write shared memory, they must first support the IPC function, that is, Specify two options when compiling and installing PHP: --enable-shmop and --enable-sysvsem.
IPC (Inter-process communication) is a Unix standard mechanism that provides a method for different processes on the same host to communicate with each other. There are three basic IPC processing mechanisms: shared memory, semaphores and message queues. In this article we mainly discuss the use of shared memory and semaphores.
Using shared memory between different processing processes is a good way to achieve mutual communication between different processes. If you write a piece of information to shared memory in one process, then all other processes can also see the written data. Very convenient. With the help of shared memory in PHP, you can achieve different results when different processes run the same PHP script. Or implement real-time query on the number of PHP running at the same time, etc.
Shared memory allows two or more processes to share a given storage area. Because data does not need to be copied between the client and server, this is the fastest type of IPC. The only trick to using shared memory is the simultaneous access of multiple processes to a given memory area.
How to create a shared memory segment? The following code can help you create shared memory.
Note that each shared memory segment has a unique ID. In PHP, shmop_open will return the ID of the created shared memory segment . Here we use $shm_id to record it. And $key is a Key value that we logically represent the shared memory segment. Different processes can share the same storage segment as long as they choose the same Key id. It is customary for us to use the hash value of a string (something like a file name) as the key id. $mode specifies how the shared memory segment is used. Since this is a new creation, the value is 'c' - which means create. If you have already created shared memory, please use 'a', which means access. The permissions defined by the $perm parameter are in octal format. Please see the UNIX file system help for permission definitions. $size defines the size of shared memory. Although it is a bit like fopen (file processing), you should not think of it as the same as file processing. You will see this later in the description.
For example:
Here we open a shared memory segment with a key value of 0xff3 –rw-r—r— format and a size of 100 bytes.
If you need an existing shared memory segment, you must set the 3rd and 4th parameters to 0 when calling shmop_open.
Under Unix, you can use a command line program ipcs to query the status of all IPC resources in the system. However, some system requirements require superuser to perform. The picture below is a section of ipcs running results.
In the picture above, the system displays 4 shared memory segments. Note that the fourth key value is 0x00000ff3, which was created by the PHP program we just ran. For the usage of ipcs, please refer to the UNIX User Manual.
How to release shared memory
The way to release shared memory is to call the PHP command: shmop_delete($id)
$id is the return value of shmop_op saved when you call shmop_open. Another way is to use UNIX management commands:
ipcrm id, id is the ID you see using ipcs. It is different from the $id in your program. But be careful, if you use ipcrm to directly delete the shared memory segment, it may cause other processes that are unaware of this situation to cause some unpredictable errors (often with unfavorable results) when referencing the shared memory that no longer exists.
How to use (read and write) shared memory
Use the function shown below to write data to shared memory
Where shmid is the handle returned by shmop_open. The $Data variable stores the data to be stored. $offset describes the position of writing the first byte from the beginning of shared memory (starting with 0).
The read operation is:
Similarly, specify $shmid, starting offset (starting from 0), and total number of reads. Return the result string. In this way, you can treat the shared memory segment as a byte array. You can read a few and write a few, and you can do whatever you want. It's very convenient.
Now, you should have no problem reading, writing, creating, and deleting shared memory in a single PHP process. However, it is obviously impossible to have only one PHP process running in actual operation. If you still use the processing method of a single process in the case of multiple processes, you will definitely encounter problems-the famous parallelism and mutual exclusion problems. For example, there are two processes that need to read and write the same memory at the same time. When two processes perform a write operation at the same time, you will get an erroneous data, because the memory segment may be the contents of the last executed process, or even a random mixture of data written by the 2 processes taking turns. The four images are different. This is obviously unacceptable. In order to solve this problem, we must introduce a mutual exclusion mechanism. The mutual exclusion mechanism is specifically described in many operating system textbooks, so I won’t repeat it here. The simplest way to implement a mutual exclusion mechanism is to use a semaphore . Semaphore is another inter-process (IPC) method, which is different from other IPC mechanisms (pipeline, FIFO, message queue). It is a counter used to control the storage of shared data by multiple processes. Similarly, you can use ipcs and ipcrm to query the status of semaphores and delete them. In PHP you can use the following functions to create a new semaphore and return a handle to the semaphore. If the semaphore pointed to by the key already exists, sem_get directly returns the handle to operate the semaphore.
$max_acquire indicates how many processes can enter the signal at the same time without waiting for the signal to be released (that is, the maximum number of processes that can process a certain resource at the same time, generally the value is one). $perm specifies permissions.
Once you successfully own a semaphore, there are only two things you can do with it: request and release. When you perform a release operation, the system will decrease the signal value by one. If it is less than 0, set it to 0. When you perform the requested operation, the system will increase the signal value by one. If the value is greater than the set maximum value, the system will suspend your processing process until other processes are released to a value less than the maximum value. Under normal circumstances, the maximum value is set to 1, so that when a process obtains a request, other subsequent processes can only wait for it to exit the mutex area and then release the semaphore before entering the mutex area and setting it to exclusive mode at the same time. Such semaphores are often called binary semaphores. Of course, if the initial value is any positive number, it indicates how many shared resource units are available for shared applications.