Overview
Shared memory is an efficient way to exchange data between applications in the same machine. A process can create a segment of memory that can be accessed by another process as long as it has the correct permissions assigned to it. Each memory segment has a unique ID (called Shmid), which points to a physical memory area that other processes can manipulate in the zone. After you create and provide the appropriate permissions, other processes in the same machine can manipulate the memory segments: read, write, and delete.
This means that applications written in C can share information with applications written in other languages, such as Java™ or PHP. They all share information, as long as they can access and understand that information. Sharing is widely used in implementations for most languages, so access should not be a problem. To understand the information, we can use a standard format, such as XML or JSON.
The use of shared memory is a quick way to exchange data between processes, primarily because the data is passed after the memory segment is created and does not involve the kernel. This method is often referred to as interprocess communication (IPC). Other IPC methods include pipelines, Message Queuing, RPC, and sockets. This ability to exchange data quickly and reliably between applications is useful when using an ecosystem of applications that need to communicate with each other. Depending on the size of the ecosystem, common methods of using databases to exchange information between applications often result in slow queries and even I/O blocking. With shared memory, no I/O slows the progress of the developer.
The proposal in this article is very simple to learn how to create and manipulate shared memory segments using PHP to store datasets that can be used by other applications. Even without a plan to exchange data with shared memory, it has many benefits in itself, because it enables applications to stay away from I/O issues. Storing data sets directly in memory has many advantages, from WEB service data caching to session sharing. It's a very useful concept that every PHP developer should know.
Shared Memory and PHP
PHP has a rich range of available extensions, as well as shared memory. With some shared functions, developers can easily manipulate memory segments without having to install any extensions.
Create a memory segment
Shared memory functions are similar to file manipulation functions, but do not need to process a stream, and you will process a shared memory access ID. The first example is the Shmop_open function, which allows you to open an existing memory segment or create a new memory segment. This function is very similar to the classic fopen function, which opens a stream for file operations and returns a resource for use by other functions that want to read or write to the open stream. Let's take a look at the Shmop_open in Listing 1.
Listing 1. Shmop_open function
Copy Code code as follows:
<?php
$systemid = 864; System ID for the shared memory segment
$mode = "C"; Access mode
$permissions = 0755; Permissions for the shared memory segment
$size = 1024; Size, in bytes, of the segment
$shmid = Shmop_open ($systemid, $mode, $permissions, $size);
?>
The first thing that appears in this function is the system ID parameter. This is the number that identifies the shared memory segment in the system. The second parameter is the access mode, which is very similar to the access mode of the fopen function. You can access one memory segment in 4 different modes:
• Mode "A", which allows you to access read-only memory segments
• Mode "W", which allows you to access read-write memory segments
• Mode "C", which creates a new memory segment, or, if the memory segment already exists, attempts to open it for reading and writing
• Mode "n", which creates a new memory segment that fails if the memory segment already exists
The third parameter is the permissions for the memory segment. You must provide a octal value here.
The fourth parameter provides the memory segment size, in bytes. Before writing a memory segment, you must allocate the appropriate number of bytes on top of it.
Note that this function returns an ID number that other functions can use to manipulate the shared memory segment. This ID is the shared memory Access ID, which, unlike the system ID, is passed as a parameter. Please be careful not to confuse the two. If it fails, Shmop_open returns FALSE.
Writing data to a memory segment
Writes data to a shared memory block using the Shmop_write function. The use of this function is simple, it accepts only 3 parameters, as shown in Listing 2.
Listing 2. Writing data to a shared memory block using Shmop_write
Copy Code code as follows:
<?php
$shmid = Shmop_open (864, ' C ', 0755, 1024);
Shmop_write ($shmid, "Hello world!", 0);
?>
This function is similar to the Fwrite function, which has two parameters: the Open stream resource (returned by fopen) and the data you want to write. The Shmop_write function also performs this task.
The first parameter is the ID returned by Shmop_open, which identifies the shared memory block that you are manipulating. The second parameter is the data that you want to store, and the last third parameter is where you want to begin writing. By default, we always use 0来 to indicate where to begin writing. Note that this function returns FALSE when it fails and returns the number of bytes written when it succeeds.
Reading data from memory segments
Reading data from shared memory segments is simple. All you need is an open memory segment and a shmop_read function. This function takes some parameters and works like Fread. See listing 3 to read the contents of a PHP file.
Listing 3. Use Shmop_read to read the contents of a file
Copy Code code as follows:
<?php
$stream = fopen (' file.txt ', ' r+ ');
Fwrite ($stream, "Hello world!");
Echo fread ($stream, 11);
?>
The process of reading the contents of a shared memory segment is similar to this, as shown in Listing 4:
Listing 4. Read the contents of a shared memory segment
Copy Code code as follows:
<?php
$shmid = Shmop_open (864, ' C ', 0755, 1024);
Shmop_write ($shmid, "Hello world!", 0);
Echo shmop_read ($shmid, 0, 11);
?>
Please pay attention to the parameters here. The Shmop_read function will accept the ID returned by Shmop_open, we already know it, but it also accepts two other parameters. The second parameter is where you want to read from the memory segment, and the third is the number of bytes you want to read. The second argument can always be 0, representing the beginning of the data, but the third parameter may be problematic because we don't know how many bytes we want to read.
This is very similar to our behavior in the Fread function, which takes two arguments: the Open stream resource (returned by fopen) and the number of bytes you want to read from the stream. Use the FileSize function, which returns the number of bytes in a file, to read it completely.
Fortunately, when using shared memory segments, the Shmop_size function returns the size (in bytes) of one memory segment, similar to the FileSize function. See listing 5.
Listing 5. The Shmop_size function returns the memory segment size, in bytes
Copy Code code as follows:
<?php
$shmid = Shmop_open (864, ' C ', 0755, 1024);
Shmop_write ($shmid, "Hello world!", 0);
$size = Shmop_size ($shmid);
Echo shmop_read ($shmid, 0, $size);
?>
Back to the top of the page
Delete a memory segment
We learned how to open, write, and read shared memory segments. To complete our CRUD classes, we also need to learn how to delete memory segments. This task can be easily accomplished using the Shmop_delete function, which takes only one parameter: the shared memory ID that we want to delete.
Listing 6. Shmop_delete mark the memory segment to be deleted
Copy Code code as follows:
<?php
$shmid = Shmop_open (864, ' C ', 0755, 1024);
Shmop_write ($shmid, "Hello world!", 0);
Shmop_delete ($shmid);
?>
This does not actually delete the memory segment. It marks the memory segment as deleted because the shared memory segment cannot be deleted if another process is using it. The Shmop_delete function marks the memory segment as deleted, preventing any other process from opening it. To remove it, we need to close the memory segment.
Close Memory segment
Opening a shared memory segment "attaches" to it. After attaching the memory segment, we can read and write to it, but after we complete the operation we must remove it from it. This is done using the Shmop_close function in Listing 7.
This is very similar to the Fclose function when working with files. After you open the stream that contains a file and read or write the data in it, we must close it or the lock will occur.
Listing 7. Use Shmop_close to separate from one memory segment
Copy Code code as follows:
<?php
$shmid = Shmop_open (864, ' C ', 0755, 1024);
Shmop_write ($shmid, "Hello world!", 0);
Shmop_delete ($shmid);
Shmop_close ($shmid);
?>
Use shared memory as a storage option
With the basic knowledge of basic CRUD operations on shared memory and shared memory segments, it is time to apply this knowledge. We can use shared memory as a unique storage option, providing the advantages of fast read/write operations and process interoperability. For WEB applications, this means:
• Cache Storage (database queries, WEB service data, external data)
• Session Storage
• Exchange of data between applications
Before continuing, I would like to introduce a small library called Simpleshm. SIMPLESHM is a small abstraction layer for using PHP to manipulate shared memory and to support easy manipulation of memory segments in an object-oriented way. When writing a small application that uses shared memory for storage, this library can help create very concise code. To learn about SIMPLESHM, visit the GitHub page.
You can work with 3 methods: Read, write, and delete. Simply instantiate an object from the class to control the open shared memory segment. Listing 8 shows the basic purpose.
Listing 8. SIMPLESHM Basic Uses
Copy Code code as follows:
<?php
$memory = new Simpleshm;
$memory->write (' Sample ');
echo $memory->read ();
?>
Note that there is no ID passed for this class. If no pass ID is passed, it randomly selects a number and opens the new memory segment for that number. We can pass a number as a parameter for the constructor to open an existing memory segment, or create a memory segment with a specific ID, as shown in Listing 9.
Listing 9. Open a specific segment of memory
Copy Code code as follows:
<?php
$new = new Simpleshm (897);
$new->write (' Sample ');
echo $new->read ();
?>
Magic Method __destructor is responsible for calling Shmop_close on the memory segment to cancel the setting of the object to separate from the memory segment. We call this "Simpleshm 101". Now let's use this method for a more advanced purpose: To use shared memory as storage. The storage dataset needs to be serialized because the array or object cannot be stored in memory. While JSON is used to serialize here, any other method, such as XML or built-in PHP serialization, is sufficient. Listing 10 shows an example.
Listing 10. Use shared memory as storage
Copy Code code as follows:
<?php
Require (' SimpleSHM.class.php ');
$results = Array (
' User ' => ' John ',
' Password ' => ' 123456 ',
' Posts ' => array (' My name is John ', ' I name is not John ')
);
$data = Json_encode ($results);
$memory = new Simpleshm;
$memory->write ($data);
$storedarray = Json_decode ($memory->read ());
Print_r ($storedarray);
?>
We succeeded in serializing an array into a JSON string, storing it in a shared memory block, reading data from it, serializing the JSON string, and displaying the stored array. This looks simple, but imagine the possibility of this code fragment. You can use it to store the results of WEB service requests, database queries, or even the template engine cache. Reading and writing in memory will result in higher performance than reading and writing on disk.
Using this storage technology is useful not only for caching, but also for data exchange between applications, as long as the data is stored in a format that is readable on both sides. Do not underestimate the power that exists within a shared Web application. This storage can be cleverly implemented in many different ways, the only limitation being the creativity and skill of the developer