This article will discuss how to use the inter-process communication mechanism-IPC (inter-process-communication) in the PhP4 environment ). The software environment discussed in this article is Linux + php4.0.4 or later. First, assume that you have installed PhP4 and Unix. To enable PhP4 to use shared memory and semaphores, you must activate the shmop and sysvsem extension modules when compiling the PhP4 program. |
Implementation Method: Add the following options When configuring configure in PHP. |
-- Enable-shmop -- enable-sysvsem |
This allows your PHP system to process related IPC functions. |
IPC (inter-process communication) is a UNIX standard communication mechanism, which provides a method for communication between different processes on the same host. There are three basic IPC processing mechanisms: Shared Memory, semaphore, and message queue. This article mainly discusses the use of shared memory and semaphores. I will introduce the message queue in the near future. |
Use shared memory segments in PHP |
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 the shared memory in a process, all other processes can also see the written data. 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 real-time query of the number of concurrent PHP operations. |
Shared memory allows two or more processes to share a given storage zone. Because data does not need to be copied between the client and the server, this is the fastest IPC. The only trick to using shared memory is the synchronous access of multiple processes to a given storage zone. |
How to create a shared memory segment? The following code helps you create shared memory. |
$ Shm_id = shmop_open ($ key, $ mode, $ perm, $ size ); |
Note that each shared memory segment has a unique ID. in PHP, shmop_open returns the ID of the created shared memory segment. Here we use $ shm_id to record it. $ Key is a key value that logically represents the shared memory segment. Different processes can share the same bucket with the same key ID. Traditionally, we use the hash value of a string (something similar to a file name) as the key ID. $ mode to indicate how to use the shared memory segment. Here, because it is a new one, the value is 'C'-the meaning of "CREATE. If you are accessing the shared memory that has been created, use 'A', -- the meaning of access. The $ perm parameter defines the access permission in octal mode. For the permission definition, see the Unix File System Help. $ Size defines the size of the shared memory. Although it is a bit like fopen (File Processing), you should not treat it like file processing. You will see a bit later. |
$ Shm_id = shmop_open (0xff3, "C", 0644,100 ); |
Here we open a shared memory segment key value 0xff3-RW-r-format, the size is 100 bytes. |
To access an existing shared memory segment, you must set the 3rd and 4 parameters to 0 in the call to shmop_open. |
Query the IPC working status |
In UNIX, you can use the command line program IPCS to query the status of all IPC resources. However, some systems require super users to execute them. Is the running result of a piece of IPCS. |
The system displays four shared memory segments. Note that the 4th key values 0x00000ff3 are created by the PHP program we just run. For instructions on IPCS usage, refer to the Unix user manual. |
How to release the shared memory? |
To release the shared memory, call the php Command: shmop_delete ($ id) |
$ ID is the return value of the shmop_op stored in the call shmop_open. Another way is to use Unix management commands: |
Ipcrm ID. ID is the ID you see in IPCS. It is different from $ ID in your program. But be careful, if you use ipcrm to directly Delete shared memory segments, other processes that do not know this situation may encounter some unpredictable Errors When referencing this no longer-existing shared memory device (often bad results ). |
How to Use (read/write) shared memory? |
Use the following function to write data to the shared memory: |
Int shmop_write (INT shmid, string data, int offset) |
Here, shmid uses the handle returned by shmop_open. $ Data variable stores the data to be stored. $ Offset describes the position of the first byte from the beginning of the shared memory (starting with 0 ). |
String shmop_read (INT shmid, int start, int count) |
Similarly, specify $ shmid, start offset (starting from 0), and total number of reads. Return result string. In this way, you can regard the shared memory segment as a byte array. It is very convenient to read a few and write a few more. |
Multi-process considerations |
Now, you should be able to read, write, create, and delete shared memory in a separate PHP process. However, it is clear that a PHP process is not running. If you still use the processing method of a single process in the case of multiple processes, you will certainly encounter problems-the famous parallel and mutex problems. For example, two processes need to read and write the same memory segment at the same time. When the two processes perform the write operation at the same time, you will get an error because the memory of this segment may be the content of the last executed process, even the data written by two processes takes turns to show a random mix of four. This is obviously unacceptable. To solve this problem, we must introduce the mutex mechanism. The mutex mechanism is described in many operating system textbooks. The simplest way to implement mutex is to use traffic signals. Semaphores are another way of inter-process communication (IPC), which is different from other IPC organizations (pipelines, FIFO, message queues. It is a stenographer used to control the storage of shared data by multiple processes. Similarly, you can use IPCS and ipcrm to query the traffic signal Usage Status and delete it. In PHP, you can use the following functions to create a new semaphore and return the handle to operate the semaphore. If the semaphore to which the key points already exists, sem_get directly returns the handle to operate the semaphore. |
Int sem_get (INT key [, int max_acquire [, int perm]) |
$ Max_acquire indicates that a maximum of several 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 process a resource at the same time. Generally, this value is one ). $ Perm indicates the access permission. |
Once you successfully have a semaphore, there are only two types of semaphore that you can do: request and release. When you perform the release operation, the system will reduce the signal value by one. If it is less than 0, it is also set to 0. When you execute the request, the system will increase the value of this signal. 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. Generally, the maximum value is set to 1, in this way, when a process receives a request, other processes can only wait for it to exit the mutex zone and release the semaphore to enter the mutex zone and set it to the exclusive mode at the same time. Such semaphores are often called two-state semaphores. Of course, if the initial value is any positive number, it indicates how many shared resource units are available to the shared application. |
The PHP format for application and release operations is as follows: |
Int sem_acquire (INT sem_identifier) Application |
Int sem_release (INT sem_identifier) released |
Specifically, sem_identifier is the return value (handle) of sem_get ). |
An example of a simple mutex Protocol |
The following is a simple mutex operation procedure. |
$ Semid = sem_get (0xee3, 1,0666 ); |
$ Shm_id = shmop_open (0xff3, "C", 0644,100 ); |
Sem_acquire ($ Semid); // apply |
/* Enter the critical section */ |
Here, the shared memory is processed |
Sem_release ($ Semid); // release |
As you can see, the implementation of mutex is very simple: Apply to enter the critical section, perform operations on the resources in the critical section (such as modifying the shared memory) to exit the critical section and release the signal. In this way, it is impossible for two processes to operate on the same shared memory segment at the same time. Because the semaphore mechanism ensures that a time slice can only be entered by one process, other processes must wait until the current process is completed before entering. |
A critical section is a code segment that does not allow concurrent processing by multiple processes at the same time. |
Note: in PHP, the semaphore occupied by the same process must be released. In a general system, processes are allowed to release signals occupied by other processes. When writing code in the critical section, be sure to carefully design the allocation of resources to avoid deadlock between A, B, and. |
IPC is widely used. For example, you can save a complex configuration file or user with specific settings between different processes to avoid repeated processing. I also used the shared memory technology to put a large number of files that must be referenced by a large number of PHP scripts into the shared memory, which significantly improves the Web service speed and eliminates some bottlenecks. There are also chat rooms and multi-channel broadcasts for its use. The power of IPC depends on the size of your imagination. It is a great honor for me to give you some inspiration in this article. Would you like to discuss this fascinating computer technology |
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,
◇ Socket Basics
◇ Generate a server
◇ Generate a client. In this chapter, you will understand the fascinating and confusing socket (sockets ). Sockets is not fully utilized in PHP. Today, you will see a server that can connect to the client and connect to the client using Socket. The server sends detailed processing information to the client.
When you see the complete socket process, you will use it in future program development. This server is an HTTP server that allows you to connect to, and the client is a Web browser, which is a single client/server relationship. ◆ Socket basic PHP uses the Berkley socket library to create its connection. You can know that socket is just a data structure. You use this socket data structure to start a session between the client and the server. This server is listening for preparing to generate a new session. When a client connects to the server, it opens a port on which the server is listening for a session. At this time, the server accepts the client connection request, then a loop is performed. Now the client can send information to the server, and the server can also send information to the client.
To generate a socket, you need three variables: one protocol, one socket type, and one public protocol type. There are three protocols for generating a socket. You can continue to read the following content to obtain the detailed protocol content.
Defining a public protocol type is an essential element for connection. The following table shows the common protocol types. Table 1: Protocols
Name/constant description
Af_inet: This is the majority of protocols used to generate sockets. It is transmitted over TCP or UDP and used for IPv4 addresses.
Af_inet6 is similar to the above, but it is used for IPv6 addresses.
The af_unix local protocol is rarely used on UNIX and Linux systems. It is generally used when the client and server are on the same server and on the same server.
Table 2: Socket Type
Name/constant description
Sock_stream is a sequential, reliable, and complete byte stream-based connection. This is the most widely used socket type, which is transmitted over TCP.
Sock_dgram is a connectionless and fixed-length transmission call. The Protocol is unreliable and UDP is used for its connection.
Sock_seqpacket is a dual-line, reliable connection that sends fixed-length data packets for transmission. This package must be fully accepted before it can be read.
The socket type sock_raw provides a single network access, which uses the ICMP public protocol. (Ping and traceroute use this Protocol)
Sock_rdm is rarely used and is not implemented in most operating systems. It is provided to the data link layer and does not guarantee the sequence of data packets. Table 3: Public Protocol
Name/constant description
The ICMP Internet Control Message Protocol is mainly used on gateways and hosts to check network conditions and report error messages.
UDP user data packet protocol, which is a connectionless and unreliable transmission protocol
TCP transmission control protocol, which is the most reliable public protocol, ensures that the data packet can reach the receiver. If an error occurs during transmission, it resends the error data packet. Now that you know the three elements that generate a socket, we will use the socket_create () function in PHP to generate a socket. The socket_create () function requires three parameters: one protocol, one socket type, and one public protocol. If the socket_create () function runs successfully, a resource type containing socket is returned. If the function fails, false is returned.
Resourece socket_create (INT protocol, int sockettype, int commonprotocol); what if you generate a socket? PHP provides several functions to manipulate the socket. You can bind a socket to an IP address, listen to the communication of a socket, and accept a socket. Now let's look at an example to learn how the 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 socket functionality to come
?> The above example generates your own server. The first line of the example,
$ Commonprotocol = getprotobyname ("TCP ");
Use the public protocol name to obtain a protocol type. TCP public protocol is used here. If you want to use UDP or ICMP, 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 generates a socket and returns a socket resource. After you have an instance with 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 port 1337. Then you need to listen to all incoming socket connections.
Socket_listen ($ socket );
After the fourth line, you need to understand all socket functions and their usage. Table 4: 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 socket errors or the final error code
Socket_close () closes a socket Resource
Socket_connect () starts a socket connection
Socket_create_listen () opens a socket listener on the specified port.
Socket_create_pair () generates a pair of identical sockets into an array.
Socket_create () generates a socket, which is equivalent to the data structure of a socket.
Socket_get_option () obtain the socket option
Socket_getpeername () obtains the IP address of a remote host similar to that of a remote host.
Socket_getsockname () gets the IP address of the local socket
Socket_iovec_add () Add a new vector to a scattered/aggregated Array
Socket_iovec_alloc () This function creates an iovec data structure that can send and receive read/write data.
Socket_iovec_delete () deletes an allocated iovec
Socket_iovec_fetch () returns the data of the specified iovec resource.
Socket_iovec_free () releases an iovec resource.
Socket_iovec_set () sets the new value of iovec data
Socket_last_error () obtains the final error code of the current socket.
Socket_listen () listens to all connections from the specified socket
Socket_read () reads data of the specified length
Socket_readv () reads data from scattered/aggregate Arrays
Socket_recv () ends data from the socket to the cache
Socket_recvfrom () accepts data from the specified socket. If no value is specified, the current socket is used by default.
Socket_recvmsg () receives messages from iovec
Socket_select () multi-path selection
Socket_send () This function sends data to the connected socket
Socket_sendmsg () sends a message to the socket
Socket_sendto () sends a message to the socket of the specified address
Socket_set_block () is set to block mode in socket
Set the socket in socket_set_nonblock () to non-block mode.
Socket_set_option () sets socket options
The socket_shutdown () function allows you to close the read, write, or specified socket
Socket_strerror () returns a detailed error of the specified error number
Socket_write () writes data to the socket Cache
Socket_writev () writes data to the scattered/aggregate array (Note: The function introduction deletes some of the original content. For more information about function usage, see the original English text or the PHP manual)
All the above functions are about socket in PHP. To use these functions, you must open your socket. If you do not open it, edit your php. INI file, remove the comments before the following line:
Extension = php_sockets.dll
If you cannot remove the annotation, use the following code to load the extension Library:
<? PHP
If (! Extension_loaded ('buckets '))
{
If (strtoupper (substr (php_ OS, 3) = "win ")
{
DL ('php _ sockets. dll ');
}
Else
{
DL ('ets ETS. so ');
}
}
?> If you do not know whether your socket is enabled, you can use the phpinfo () function to determine whether the socket is enabled. You can check the phpinfo information to check whether the socket is enabled. For example:
View the socket information of phpinfo () ◆ generate a server. Now we have improved the first example. You need to listen to a specified socket and process user connections. <? 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 a server is generated, not a Web page. If you try to use a web browser to run this script, it is likely to exceed 30 seconds. You can use the following code to set an unlimited running time, but we recommend that you use a command prompt to run it.
Set_time_limit (0 );
Perform a simple test on the script in your command prompt:
Php.exe example01_server.php
If you have not set the PHP interpreter in the system environment variable, you can specify the detailed path for php.exe. When you run this server, you can connect to port 1337 through remote login (Telnet) to test this server. For example, the preceding server has three problems: 1. It cannot accept multiple connections. 2. It only completes a unique command. 3. You cannot connect to this server through a web browser.
This first problem is easy to solve. You can use an application to connect to the server every time. However, the problem is that you need to use a web page to connect to the server, which is more difficult. You can make your server accept the connection and then send some data to the client (if it must be written), close the connection and wait for the next connection.
Based on the previous Code, the following code is generated for your new server: <? PHP
// Set up our socket
$ 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 in on this socket $ connection = socket_accept ($ socket );
Printf ("Socket connected/R/N ");
// Check to see if there is 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 stored ED/R/N ");
Printf ("buffer:". $ buffer. "/R/N ");
}
Socket_close ($ connection );
Printf ("closed the socket/R/n/R/N ");
}
?> What does this server do? It initializes a socket and opens a cache to send and receive data. It waits for a connection. Once a connection is generated, it prints "Socket connected" on the server screen. This server checks the buffer zone. If there is data in the buffer zone, it sends the data to the connected computer. Then, it sends the receiving information of the Data. Once it accepts the information, it stores the information in the data, allows the connected computer to know the information, and closes the connection. When the connection is closed, the server starts to process the next connection. (For poor translation, attach the original article)
This is what the server does. It initializes the socket and the buffer that you use to receive
And send data. Then it waits for a connection. Once a connection is created it prints
"Socket connected" to the screen the server is running on. The server then checks to see 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 takes es Information it stores
It in the data, lets the connected computer know that it has stored ed the information, and
Then closes the connection. After the connection is closed, the server starts the whole
Process again. ◆ it is easy to generate a client to handle the second problem. You need to generate a PHP page to connect to a socket, send some data to its cache, and process it. Then you have another processed data, and you can send your data to the server. Connect to another client and it will process the data.
To solve the second problem is very easy. You need to create a PHP page that connects
A socket, receive any data that is in the buffer, and process it. After you have processed
Data in the buffer you can send your data to the server. When another client connects, it
Will process the data you sent and the client will send more data back to the server. The following example demonstrates the use of socket: <? PHP
// Create the socket and connect
$ Socket = socket_create (af_inet, sock_stream, sol_tcp );
$ Connection = socket_connect ($ socket, 'localhost', 1337 );
While ($ buffer = fig ($ 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 socket
If (! Socket_write ($ socket, "Some data/R/N "))
{
Echo ("<p> write failed </P> ");
}
// Read any response from the socket
While ($ buffer = fig ($ 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 in this example demonstrates how to connect the client to the server. The client reads data. If this is the first connection to reach this loop, the server will send "no data" to the client. If this happens, the client is connected. The client sends its data to the server, and the data is sent to the server. The client waits for a response. Once a response is received, it writes the response to the screen.