Communication between processes in PHP
PHP has several features that allow different PHP processes communicate with each other but most programmers use unknown. The paper explores how to use shared memory and semaphores from PHP and a new world of possibilities a reality.
Communication between processes in PHP
"Preoptimization is the root of all evil (Donald Knuth)"
In this article we will explain how to handle shared memory and semaphores from PHP, it is necessary to have php compiled with the following options:
The two extensions that we use are the extension of shared memory and semaphore extension, we aver that we do with each of them then ..
What is IPC?
IPC (Inter-process communication) mechanism is a standard Unix processes to communicate with each other. Processes reside, it's clarification, all on the same machine. Basically IPC defines 3 different forms of communication: message queues, shared memory segments and semaphores. In this article we will discuss the use of semaphores and shared memory.
Using Shared Memory from PHP
The use of shared memory segments is a very good way of communicating processes together. Basically a segment of memory that can be shared by multiple processes, if a process writes to the segment the other processes can see the data is defined. In PHP we can control with this technique the number of running, or put data in memorua preventing other processes have to generate the same information that was generated by other processes and processes. In critical applications using cache memory as a temporary storage is widely more efficient than using a file-system file
To create a shared memory segment used:
$ Shm_id = shmop_open ($ key, $ mode, $ perm, $ size);
- $ Key is the number that idnetifica the shared memory segment, all processes wishing to access this same segment should know this number as a key to access the segment.
- $ Mode is the mode of creation, "c" is used to create a segment while "a" is used to access a segment already created
- $ Perm defines the permissions of the segment according to the mechanism of Unix permissions
- Defined $ size The size of the segment
The function returns an id that debermos used to read / write to the segment. It is similar to a file handle as the functions used to manipulate shared memory are different.
$ Shm_id = shmop_open (0xff3, "c", 0644, 100);
In the example we create a shared memory segment of 100 bytes.
If we want to access an existing segment I use shmop_open by setting to 0 the third and fourth parameters of the function. If you want to create or access a second segment corresponds proceed as if we were creating it, if the segment already exists simply access the same.
What did we do?
There are some Unix utilities that can be called from the command line to monitor and control IPC resources, for example we can use "ipcs" to check what resources are created and some of the same parameters.
------ Shared Memory Segments -------- key shmid owner perms bytes nattch status0x00280267 30x00000000 1048576 644 0 1 root nobody 600 46084 10 46084 600 dest0x00000000 February 8 dest0x00000ff3 nobody nobody 131 644 100 0 ------ Semaphore Arrays -------- key semid owner perms nsems status0x00280269 0 666 root 14 ------ Message Queues -------- key msqid owner perms used-bytes messages
As we can see we have 4 shared memory segments created, the latter with (key 0x0000ff3) is that we believe in our example. We can view the properties of the segments, as the creator, permissions, size and number of processes that are using the segment in the output of ipcs command.
Returning to PHP
If we remove a shared memory segment we can use the following instruction from PHP:
shmop_delete ($ id);
The $ id is the one we use the function shmop_open promptly returned it to create or access the segment.
If we remove the segment from the command line you can use the 'ipcrm shmid' eg 'ipcrm 131' command (in our example) would eliminate the segment created from PHP.
WARNING: If you use ipcrm as "root" must be very careful checking that the segment segment will be really clear that we want to eliminate. If we remove other segments belonging to other processes we can produce unexpected results and generally are pretty bad ...
Reading and writing data
To write data to a shared memory segment used:
shmop_write int (int shmid, string data, int offset)
shmid is the id which remanded shmop_open, data is the data (what else?) and the offset is the offset within the segment (0 to start writing at the beginning of this)
To read use:
shmop_read string (shmid int, int start, int count)
We indicate the position (offset) from which we read (0 for the start of the segment) and the number of bytes to read. Using shared memory data does not have any meaning beyond being strips of bytes, in most implementations is good to build classes that handle shared memory in charge of providing interfaces for guaradar strings, objects and other data types. The class is then responsible for handling the lengths and abstract the concept of strip bytes in memory programmer.
We will have no problem creating, accessing, reading and writing a shared memory segment from a single isolated process. But we can find some problems when more than one process at the same time try to use the segment, we are about to enter the fascinating world of concurrent processes and the problem of mutual exclusion.
Suppose we have two processes reading and writing data from the same shared memory segment. If two processes try to write data to the same position in memory at the same time can get inconsistencies, this is known as the "problem of mutual exclusion" There is a lot of information and literature on the subject mainly in books on operating systems. A simple way to achieve mutual exclusion is using semaphores, and is the mechanism that we study below.
The traffic lights are another IPC resources, we can see information about the system semaphores with ipcs and remove ipcrm. To create a semaphore from Php is used:
sem_get int (int key [, int max_acquire [, int perm]])
The semaphore is created if necessary or if it already existed accessed. The function returns a handle that is used to manipulate the semaphore. max_acquiere indicates the maximum number of processes that can acquire the semaphore without release, the default is 1. Permissions setean as constumbre.
Once we have the semaphore we can do two things with: acquire and release. When we acquire a semaphore can think that we are increasing and if we try to increase it beyond the amount max_acquire seteada with the process is blocked until another process releases the semaphore locked and enable the process to buy. In binary semaphores, the most common in 90 \% of cases only one process can acquire the semaphore, other processes that want to acquire the semaphore will remain blocked until the process holding the semaphore releases it.
To acquire and release semaphores use:
sem_acquire int (int sem_identifier)
sem_release int (int sem_identifier)
Where is the identifier we got with sem_get
A simple mutual exclusion protocol.
We can use the following protocol to achieve mutual exclusion from PHP:
$ Semid = sem_get (0xee3, 1.0666) = $ shm_id shmop_open (0xff3, "c", 0644, 100); sem_acquire ($ semid) ;/ * If we are here we are alone! * / WRITE TO THE SHARED SEGMENT HEREsem_release ($ semid);
As we can see the mechanism is simple, the semaphore is acquired, does something and then the semaphore is released. We can be sure that it is impossible for two processes simultaneously writing this because once one acquires the semaphore others are blocked until the semaphore is released. The lines between sem_release sem_acquire and are known as "critical section", ie areas where we do not want two processes simultaneously attend.
An interesting point is that in PHP semaphore implementation process that releases the semaphore should be the same as acquired. A process can not release a semaphore acquired by another process. This is not common in other languages that use IPC so we must take this into account.
Importantly, we only have to worry about mutual exclusion between writers, that more than one process read the same shared memory segment at a time no problem but if there is any "writer" process then the process should be the one to access memory. This is a known concurrency problem known as the problem of readers-writers.
There are several applications for IPC, from some simple optimization recursoso as stored in shared memory configuration files parsed to advanced search engines, or systems authentication cache.