Overview
Shared memory is an effective way to exchange data between applications in the same machine. A process can create a memory segment that can be accessed by other processes as long as it is assigned the correct permissions. Each memory segment has a unique ID (called Shmid), which points to a physical memory area where other processes can manipulate it. Once the appropriate permissions have been created and provided, other processes in the same machine can manipulate these 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 can all share information as long as they can access and understand that information. There is widespread use of implementations within a share for most languages, so access should not be a problem. To understand 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 approach 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 ways to use databases to exchange information between applications often result in slow queries and even I/O blocking. With shared memory, no I/O slows developers ' progress.
The proposal in this article is simple enough to learn how to use PHP to create and manipulate shared memory segments, using them to store datasets that can be used by other applications. Even without a plan to exchange data using shared memory, it itself has many benefits, because it enables applications to stay away from I/O problems. storing datasets 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
A shared memory function is similar to a file manipulation function, but there is no 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 the Code code as follows:
$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 the 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 pattern, which is very similar to the access mode of the fopen function. You can access a 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, try to open it for read and write
• Mode "n", which creates a new memory segment that fails if the memory segment already exists
The third parameter is the permission for a memory segment. You must provide an octal value here.
The fourth parameter provides a 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. Be careful not to confuse the two. If it fails, Shmop_open will return FALSE.
Writing data to a memory segment
Use the Shmop_write function to write data to a shared memory block. The use of this function is simple, and it accepts only 3 parameters, as shown in Listing 2.
Listing 2. Using Shmop_write to write data to a shared memory block
Copy the Code code as follows:
$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: an 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 of your operation. The second parameter is the data you want to store, and the last third parameter is where you want to start writing. By default, we always use zero to indicate where to start writing. Note that this function returns FALSE on failure and returns the number of bytes written when successful.
Reading data from a memory segment
Reading data from a shared memory segment is straightforward. You only need an open memory segment and the Shmop_read function. This function accepts some parameters and works like Fread. See listing 3, reading the contents of a PHP file.
Listing 3. Use Shmop_read to read the contents of a file
Copy the Code code as follows:
$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 the Code code as follows:
$shmid = Shmop_open (864, ' C ', 0755, 1024);
Shmop_write ($shmid, "Hello world!", 0);
Echo shmop_read ($shmid, 0, 11);
?>
Please note the parameters here. The Shmop_read function will accept the ID returned by Shmop_open, which we already know, but it also accepts two additional 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, which represents 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: an 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 a memory segment, similar to the FileSize function. See listing 5.
Listing 5. The Shmop_size function returns the memory segment size, in bytes
Copy the Code code as follows:
$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 top of page
Delete a memory segment
We learned how to open, write, and read shared memory segments. To complete our CRUD class, we also need to learn how to delete memory segments. This task can be done easily using the Shmop_delete function, which accepts only one parameter: the shared memory ID that we want to delete.
Listing 6. Shmop_delete mark the memory segment to be deleted
Copy the Code code as follows:
$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 while another process is using it. The Shmop_delete function marks the memory segment as deleted, preventing any other process from opening it. To delete it, we need to close the memory segment.
Close Memory segment
Opening a shared memory segment is "attached" to it. After attaching the memory segment, we can read and write in it, but after the operation is complete, 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 a stream that contains a file and read or write data in it, we must close it or the lock will occur.
Listing 7. Use Shmop_close to separate a memory segment
Copy the Code code as follows:
$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 the 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 benefits of fast read/write operations and process interoperability. For a WEB application, this means:
• Cache Storage (database queries, WEB service data, external data)
• Session Storage
• Data exchange between applications
Before proceeding, I would like to introduce a small library called Simpleshm. SIMPLESHM is a small abstraction layer that uses PHP to manipulate shared memory, enabling easy manipulation of memory segments in an object-oriented manner. When writing small applications that use shared memory for storage, this library helps to create very concise code. To learn about SIMPLESHM, please visit the GitHub page.
You can use 3 methods for processing: Read, write, and delete. By simply instantiating an object from the class, you can control the open shared memory segment. Listing 8 shows the basic purpose.
Listing 8. SIMPLESHM Basic Uses
Copy the Code code as follows:
$memory = new Simpleshm;
$memory->write (' Sample ');
echo $memory->read ();
?>
Note that there is no ID passed for the 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 to create a memory segment with a specific ID, as shown in Listing 9.
Listing 9. Open a specific segment of memory
Copy the Code code as follows:
$new = new Simpleshm (897);
$new->write (' Sample ');
echo $new->read ();
?>
The Magic Method __destructor is responsible for calling Shmop_close on the memory segment to de-set the object to be detached from the memory segment. We refer to this as "Simpleshm 101". Now let's use this method for more advanced purposes: using shared memory as storage. The storage dataset needs to be serialized because the array or object cannot be stored in memory. Although JSON is used here to serialize, any other method, such as XML or the built-in PHP serialization functionality, is sufficient. Listing 10 shows an example.
Listing 10. Use shared memory as storage
Copy the Code code as follows:
Require (' SimpleSHM.class.php ');
$results = Array (
' User ' = ' John ',
' Password ' = ' 123456 ',
' posts ' = = Array (' My name is John ', ' My name is not John ')
);
$data = Json_encode ($results);
$memory = new Simpleshm;
$memory->write ($data);
$storedarray = Json_decode ($memory->read ());
Print_r ($storedarray);
?>
We successfully serialized an array into a JSON string, storing it in a shared memory block, reading the data from it, serializing the JSON string, and displaying the stored array. This may seem simple, but imagine the possibilities that this code snippet brings. You can use it to store the results of a WEB service request, a database query, or even a template engine cache. Read and write in memory will bring higher performance than read and write on disk.
Using this storage technology is useful not only for caching, but also for exchanging data between applications, as long as the data is stored in a readable format on both ends. Do not underestimate the power of WEB applications that exist within a share. This storage can be cleverly implemented in many different ways, with the only limitation being the developer's creativity and skills