This article discusses how to use the interprocess communication mechanism--IPC (inter-process-communication) in a PHP4 environment. The software environment discussed in this article is linux+php4.0.4 or later. First, let's say you've installed PHP4 and UNIX, and in order for PHP4 to be able to use shared memory and semaphores, you must activate both the SHMOP and Sysvsem extension modules when compiling the PHP4 program. |
Implementation: Add the following options when setting up PHP (Configure). |
--enable-shmop--enable-sysvsem |
This allows your PHP system to handle the relevant IPC functions. |
IPC (inter-process communication) is a standard UNIX communication mechanism that provides a way to communicate with each other in different processes on the same host. There are 3 basic IPC processing mechanisms: Shared memory, semaphores, and message queues, respectively. In this article, we mainly discuss the use of shared memory and semaphores. About the message queue, the author in the near future will also be specifically introduced. |
Using shared memory segments in PHP |
Using shared memory between different processing processes is a good way to achieve communication between different processes. If you write a piece of information to a shared memory in a process, all other processes can also see the data being written. Very convenient. With the help of shared memory in PHP, you can implement different processes to return different results when running the same PHP script. Or to implement real-time queries on the number of simultaneous PHP runs, and so on. |
Shared memory allows two or more processes to share a given storage area. Because the data does not need to be replicated between the client and the server, this is the fastest IPC. The only trick to using shared memory is the simultaneous access of multiple processes to a given storage area. |
How to create a shared memory segment. The following code can help you build shared memory. |
$shm _id = Shmop_open ($key, $mode, $perm, $size); |
Note that each shared memory segment has a unique ID, and in PHP, Shmop_open returns the ID of the established shared memory segment, where 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 segment as long as the same key ID is selected. It is customary for us to use a hash value of a string (something like a filename) as the key ID. $mode indicates how shared memory segments are used. This is because it is new, so the value is ' C '-take the meaning of create. If you are accessing shared memory that you have already built, use the ' a ',--for access. The $perm parameter defines the access permissions, 8, and the Unix file system Help for permission definitions. $size defines the size of the shared memory. Although a bit like fopen (file processing) You don't want to be treated like a file. The following description you will see a little bit. |
$shm _id = Shmop_open (0XFF3, "C", 0644, 100); |
Here we open a shared memory segment key value 0xff3–rw-r-r-format with a size of 100 bytes. |
If you need to access an existing shared memory segment, you must set the 3rd, 4 parameters to 0 in the call Shmop_open. |
Query for IPC working status |
Under UNIX, you can use a command-line program to IPCS all the IPC resource states in the system. However, some system requirements require superuser to perform. The following figure shows the results of a IPCS operation. |
The system shows 4 shared memory segments in the image above, noting that the 4th key value is 0X00000FF3 is created by the PHP program we just ran. Refer to the UNIX user manual for the use of IPCS. |
How do I free shared memory? |
The way to free shared memory is to invoke the PHP Directive: Shmop_delete ($ID) |
$id is the return value of the shmop_op that you call Shmop_open. Another option is to use UNIX management directives: |
IPCRM ID, ID is the ID you see with IPCS. It's not the same as the $id in your program. Be careful, however, that if you use IPCRM to delete shared memory segments, it is possible that other processes that do not know the situation have some unpredictable errors (often bad results) when referencing this defunct shared memory device. |
How do I use (read and write) shared memory? |
Write data to shared memory using the functions shown below |
int shmop_write (int shmid, string data, int offset) |
Where Shmid is the handle returned with the Shmop_open. The $Data variable holds the data to be stored. $offset describes where to write the first byte from the start of shared memory (starting with 0). |
String Shmop_read (int shmid, int start, int count) |
Also, indicate the $SHMID, begin the offset (starting at 0), and the total number of reads. Returns the result string. This way, you can think of a shared memory segment as a byte array. Read a few and write a few, do what you want to do, very convenient. |
Considerations for multiple process issues |
Now you should have no problem reading, writing, creating, and deleting shared memory in a separate PHP process. However, it is clear that the actual operation is not just a PHP process in operation. If you are using a single process in the case of multiple processes, you are bound to encounter problems----well-known parallel and mutex issues. For example, there are 2 processes that need to read and write to the same memory at the same time. When two processes write at the same time, you will get the wrong data, because the memory will probably be the content of the last process, or even the data written by 2 of processes randomly appear a mixed four-image. This is clearly unacceptable. In order to solve this problem, we must introduce mutual exclusion mechanism. The mutual exclusion mechanism is specifically described in the textbooks of many operating systems, and there is little repetition here. The easiest way to implement a mutex is to use a semaphore. Semaphores are another way of interprocess communication (IPC), which differs from other IPC mechanisms (pipelines, FIFO, message queues). It is a register that controls the storage of shared data by multiple processes. In the same way, you can use IPCS and IPCRM to implement a query of the state of the semaphore and to implement a delete operation. In PHP you can use the following function to create a new semaphore and return a handle to the semaphore. If the key points to a semaphore that already exists, the Sem_get directly returns the handle that is manipulating the semaphore. |
int Sem_get int key [, int max_acquire [, int perm]] |
$max _acquire indicates that a maximum of several processes can be entered at the same time without waiting for the signal to be released (that is, the number of processes that handle a resource at the same time, typically the value is one). The $perm indicates access rights. |
Once you successfully have a semaphore, you can do only 2 kinds of it: request, release. When you perform a release operation, the system will reduce the signal value by one. If less than 0, it is also set to 0. And when you perform a request operation, the system will add the signal value one, if the value is greater than the set maximum then the system will suspend your process until the other process is released to less than the maximum value. In general, the maximum is set to 1, so that when a process obtains a request, the other subsequent process can only wait for it to exit the mutex and then release the semaphore before it can enter the mutex and be set as exclusive. Such a semaphore is often referred to as a dual-state signal volume. Of course, if the initial value is any positive number, it indicates how many shared resource units are available for shared applications. |
The PHP format for the request and release operation is as follows: |
int sem_acquire (int sem_identifier) request |
int sem_release (int sem_identifier) free |
Where Sem_identifier is the return value (handle) of the call Sem_get. |
An example of a simple mutex protocol |
Here is a very simple mutex operation. |
$semid =sem_get (0xee3,1,0666); |
$shm _id = Shmop_open (0XFF3, "C", 0644, 100); |
Sem_acquire ($semid); //application |
/* Enter critical section/* |
Here, the shared memory is processed |
Sem_release ($semid); //Release |
As you can see, the implementation of the mutex is simple: The request enters the critical section, operates on the critical area resources (such as modifying shared memory), exits the critical section and releases the signal. This ensures that there are no simultaneous 2 processes in the same time slice that can operate on the same segment of shared memory. Because the semaphore mechanism ensures that a time slice can only be entered by one process, the other processes must wait for the current process to complete before they can enter. |
Critical areas are generally those that do not allow multiple concurrent processes to be processed concurrently by code snippets. |
It is important to note that in PHP, the same process must be freed from the amount of semaphore it occupies. Allows processes to release signals that other processes occupy in the general system. In writing critical section Code must be careful to design the allocation of resources, to avoid a and so b,b, such as a deadlock situation occurred. |
The application of IPC is very extensive. For example, save an interpreted complex profile, or a specific set of users, between different processes to avoid duplication of processing. I've also used shared memory technology to put a large file of PHP scripts into shared memory, which significantly improves the speed of Web services and eliminates some bottlenecks. About its use there are chat rooms, multicast, and so on. The power of IPC depends on the size of your imagination. If this article has a little inspiration for you, I would be honored. Willing to talk to you about this fascinating computer technology |
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
◇socket Foundation
◇ Create a server
◇ Create a client in this chapter you will learn about attractive and confusing sockets (Sockets). Sockets is a feature that is not fully exploited in PHP. Today you will see the creation of a server that can use a client-side connection and connect using a socket on the client, and the server will send detailed processing information to the client.
When you see the full socket process, you will use it later in the program development. This server is an HTTP server that lets you connect, the client is a Web browser, this is a single client/server relationship. Socket Basics
PHP uses the Berkley socket library to create its connection. You can see that the socket is nothing more than a data structure. You use this socket data structure to start a session between the client and the server. This server is always listening to prepare to generate a new session. When a client connects to the server, it opens a session on a port on which the server is listening. At this point, the server side accepts the client's connection request, and then a loop is made. Now the client is able to send information to the server, and the server can send messages to the client.
To produce a socket, you need three variables: a protocol, a socket type, and a common protocol type. There are three protocols available for a socket to choose from, and continue to look at the content below to get detailed protocol content.
Defining a common protocol type is an essential element for a connection. The following table looks at the types of common protocols that we have. Table I: Agreement
Name/Constant Description
Af_inet This is most of the protocol used to generate sockets, using TCP or UDP for transmission, used in IPV4 addresses
Af_inet6 is similar to the above, but is used in IPV6 address
Af_unix local protocols, used on UNIX and Linux systems, are rarely used, typically when the client and server are on the same platform
Table II: Socket type
Name/Constant Description
Sock_stream This protocol is a sequential, reliable, data-complete, byte-stream based connection. This is the most commonly used socket type, which is transmitted using TCP.
Sock_dgram This protocol is connectionless, fixed-length transmission calls. The protocol is unreliable and uses UDP to connect to it.
Sock_seqpacket This protocol is a two-way, reliable connection that sends fixed-length packets for transmission. This package must be fully accepted for reading.
Sock_raw This socket type provides a single network access, this socket type uses ICMP public protocol. (Ping, traceroute Use this Protocol)
SOCK_RDM This type is rarely used and is not implemented on most operating systems, it is provided to the data link layer for use, does not guarantee packet Order Table III: public Agreement
Name/Constant Description
ICMP Internet Control Message Protocol, used primarily on gateways and hosts to check network conditions and report error messages
UDP User Data Packet protocol, which is a connectionless, unreliable transmission protocol
TCP Transmission Control Protocol, this is a reliable public protocol with the most use, it can ensure that the packet can reach the recipient, if there is an error in the transmission process, it will resend the error packet. Now that you know the three elements that produce a socket, then we use the Socket_create () function in PHP to produce a socket. This socket_create () function requires three parameters: a protocol, a socket type, and a public protocol. The Socket_create () function successfully returns a resource type containing the socket, or false if it does not succeed.
Resourece socket_create (int protocol, int sockettype, int commonprotocol); Now you have a socket, and then. PHP provides several functions for manipulating sockets. You can bind a socket to an IP, listen for a socket, and accept a socket; Now let's look at an example of how a function generates, accepts, and listens to a socket. <?php
$commonProtocol = Getprotobyname ("TCP");
$socket = Socket_create (Af_inet, Sock_stream, $commonProtocol);
Socket_bind ($socket, ' localhost ', 1337);
Socket_listen ($socket);
More sockets functionality to come
?> The above example creates a server side of your own. Example the first line,
$commonProtocol = Getprotobyname ("TCP");
Use the public protocol name to obtain a protocol type. The TCP public protocol is used here, and if you want to use UDP or ICMP protocol, you should change the parameter of the Getprotobyname () function to "UDP" or "ICMP." Another option is to specify SOL_TCP or SOL_UDP in the socket_create () function instead of using the Getprotobyname () function.
$socket = Socket_create (Af_inet, Sock_stream, sol_tcp);
The second line of the example is the instance that produces a socket and returns a socket resource. After you have an instance of a socket resource, you must bind the socket to an IP address and a port.
Socket_bind ($socket, ' localhost ', 1337);
Here you bind the socket to the local computer (127.0.0.1) and bind the socket to your 1337 port. Then you'll need to listen for all incoming socket connections.
Socket_listen ($socket);
After line fourth, you'll need to know all the socket functions and their usage. Table four: Socket functions
Function Name Description
Socket_accept () accepts a socket connection
Socket_bind () binds the socket to an IP address and port
Socket_clear_error () Clears the socket error or the last error code
Socket_close () closes a socket resource
Socket_connect () Start a socket connection
Socket_create_listen () opens a socket listener on the specified port
Socket_create_pair () produces a pair of indistinguishable sockets into an array
Socket_create () produces a socket, which is equivalent to generating a socket data structure
Socket_get_option () Get socket option
Socket_getpeername () Gets the IP address of a remote similar host
Socket_getsockname () Gets the IP address of the local socket
Socket_iovec_add () adds a new vector to a scatter/aggregate array
Socket_iovec_alloc () This function creates a IOVEC data structure capable of sending and receiving read and write
Socket_iovec_delete () deletes an already allocated Iovec
Socket_iovec_fetch () returns the data for the specified Iovec resource
Socket_iovec_free () frees a Iovec resource
Socket_iovec_set () sets the Iovec data new value
Socket_last_error () Gets the last error code for the current socket
Socket_listen () listens for all connections by the specified socket
Socket_read () reads the specified length of data
SOCKET_READV () reads data coming from a scatter/aggregate array
SOCKET_RECV () end data from socket to cache
Socket_recvfrom () accepts data from the specified socket and, if not specified, the default current socket
Socket_recvmsg () received a message from Iovec
Socket_select () multi-channel selection
Socket_send () This function sends data to the connected socket
SOCKET_SENDMSG () Send message to socket
Socket_sendto () sends a message to the socket at the specified address
Socket_set_block () is set to block mode in the socket
Socket_set_nonblock () socket is set to not block mode
Socket_set_option () Set socket options
Socket_shutdown () This function allows you to close a read, write, or specified socket
Socket_strerror () returns a detailed error for the specified error number
Socket_write () write data to the socket cache
Socket_writev () write data to a scatter/aggregate array (note: The function introduces the deletion of some of the original content, the function of the detailed use of recommendations to refer to the original English, or reference PHP manual)
All of the above functions are PHP about sockets, using these functions, you have to open your socket, if you do not open, please edit your php.ini file, remove the following line of comments:
Extension=php_sockets.dll
If you cannot remove the annotation, use the following code to load the extension library:
<?php
if (!extension_loaded (' Sockets '))
{
if (Strtoupper (substr (Php_os, 3)) = = "WIN")
{
DL (' Php_sockets.dll ');
}
Else
{
DL (' sockets.so ');
}
}
?> If you don't know if your socket is open, then you can use the Phpinfo () function to determine if the socket is open. You see if the socket is open by looking at the Phpinfo information. The following figure:
View Phpinfo () information about the socket
Create a server
Now let's make the first example perfect. You need to listen for a specified socket and handle the user's connection. <?php
$commonProtocol = Getprotobyname ("TCP");
$socket = Socket_create (Af_inet, Sock_stream, $commonProtocol);
Socket_bind ($socket, ' localhost ', 1337);
Socket_listen ($socket);
Accept any incoming connections to the server
$connection = Socket_accept ($socket);
if ($connection)
{
Socket_write ($connection, "you have connected to the socket.../n/r");
}
?> You should use your command prompt to run this example. The reason is that this will produce a server instead of a Web page. If you try to run the script using a Web browser, chances are that it will exceed the 30-second limit. You can use the following code to set an unlimited run time, but it is recommended that you use a command prompt to run.
Set_time_limit (0);
Do a simple test of this script at your command prompt:
Php.exe example01_server.php
If you do not set the path of the PHP interpreter in the system's environment variables, you will need to specify a detailed path to the Php.exe. When you run this server side, you can connect to the port 1337来 by remote login (telnet) to test the server. The following figure: the server side of the above has three questions: 1. It cannot accept multiple connections. 2. It completes only one command. 3. You cannot connect to this server through a Web browser.
This first problem is easier to solve and you can use an application to connect to the server each time. But the problem is that you need to use a Web page to connect to the server, which is more difficult. You can have your server accept the connection, and then some data to the client (if it must be written), close the connection and wait for the next connection.
On the basis of the previous code to improve, generate the following code to do your new server side: <?php
Set up our sockets
$commonProtocol = Getprotobyname ("TCP");
$socket = Socket_create (Af_inet, Sock_stream, $commonProtocol);
Socket_bind ($socket, ' localhost ', 1337);
Socket_listen ($socket);
Initialize the buffer
$buffer = "NO DATA";
while (true)
{
Accept Any connections coming the this socket $connection = socket_accept ($socket);
printf ("Socket connected/r/n");
Check to the If there are anything in the buffer
if ($buffer!= "")
{
printf ("Something is in the buffer...sending data.../r/n");
Socket_write ($connection, $buffer. "/r/n");
printf ("wrote to socket/r/n");
}
Else
{
printf ("No Data in the buffer/r/n");
}
Get the input
while ($data = Socket_read ($connection, 1024, php_normal_read))
{
$buffer = $data;
Socket_write ($connection, "Information received/r/n");
printf ("Buffer:"). $buffer. "/r/n");
}
Socket_close ($connection);
printf ("Closed the socket/r/n/r/n");
}
?> What to do with this server side. It initializes a socket and opens a cache to send and receive data. It waits for a connection, and once it produces a connection, it prints "Socket connected" on the server-side screen. This server checks the buffer, and if there is data in the buffer, it sends the data to the connected computer. It then sends the acceptance information for this data, and once it accepts the information, it saves the information to the data and lets the connected computer know the information, and then closes the connection. When the connection is closed, the server starts processing the next connection again. (bad translation, attached to the original text)
This is what the server does. It initializes the socket and the buffer
and send data. Then it waits for a connection. Once A connection is created it prints
' Socket connected ' to the ' screen ' is running on. The server then checks to if
There is anything in the buffer; If there is, it sends the data to the connected computer.
After it sends the data it waits to receive information. Once It receives information it stores
It in the data, lets the connected computer know, it has received the information, and
Then closes the connection. After the connection is closed, the server starts the whole
Process again.
It is easy to produce a client to handle the second problem. You need to generate a PHP page to connect a socket, send some data into it's cache and process it. Then you have to deal with the data after the Dayton, you can send your data to the server. On a different client connection, it will process those data.
To solve the second problem are very easy. You are need to create a PHP page which connects to
A socket, receive any data of this is in the buffer, and process it. After you have processed the
Data in the ' buffer ' can send your data to the server. When another client connects, it
'll process the data you sent and the client would send more data back to the server.
The following example demonstrates the use of sockets: <?php
Create the socket and connect
$socket = Socket_create (Af_inet, Sock_stream, sol_tcp);
$connection = Socket_connect ($socket, ' localhost ', 1337);
while ($buffer = Socket_read ($socket, 1024, php_normal_read))
{
if ($buffer = = "NO DATA")
{
Echo ("<p>no data</p>");
Break
}
Else
{
Do something with the data in the buffer
Echo ("<p>buffer Data:"). $buffer. "</p>");
}
}
Echo ("<p>writing to Socket</p>");
Write some test data to our sockets
if (!socket_write ($socket, "SOME data/r/n"))
{
Echo ("<p>write failed</p>");
}
Read any response from the socket
while ($buffer = Socket_read ($socket, 1024, php_normal_read))
{
Echo ("<p>data sent Was:some data<br> Response was:". $buffer. "</p>");
}
Echo ("<p>done Reading from socket</p>");
?> The code for this example demonstrates that the client connects to the server. The client reads the data. If this is the first time a connection is reached for this loop, the server will send "NO DATA" back to the client. If this happens, the client is on top of the connection. The client sends its data to the server, the data is sent to the server, and the client waits for a response. Once the response is received, it will write the response to the screen.