The way to complete interprocess communication by manipulating Linux message queues in PHP

  • 2020-03-31 20:55:18
  • OfStack

On the concept and implementation of Linux system process communication to view: http://www.ibm.com/developerworks/cn/linux/l-ipc/
On Linux system the concept and implement of message queue to view: http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/
The sysvmsg module of PHP is the encapsulation of the System V message queue function family in System V IPC supported by Linux System. We need to use the functions provided by the sysvmsg module to communicate between processes. Let's start with a sample code _1:
 
<?php 
$message_queue_key = ftok(__FILE__, 'a'); 
$message_queue = msg_get_queue($message_queue_key, 0666); 
var_dump($message_queue); 
$message_queue_status = msg_stat_queue($message_queue); 
print_r($message_queue_status); 
//Write to the message queue
msg_send($message_queue, 1, "Hello,World!"); 
$message_queue_status = msg_stat_queue($message_queue); 
print_r($message_queue_status); 
//Read from the message queue
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT); 
print_r($message."rn"); 
msg_remove_queue($message_queue); 
?> 

The result of this code is as follows:
 
resource(4) of type (sysvmsg queue) 
Array 
( 
[msg_perm.uid] => 1000 
[msg_perm.gid] => 1000 
[msg_perm.mode] => 438 
[msg_stime] => 0 
[msg_rtime] => 0 
[msg_ctime] => 1279849495 
[msg_qnum] => 0 
[msg_qbytes] => 16384 
[msg_lspid] => 0 
[msg_lrpid] => 0 
) 
Array 
( 
[msg_perm.uid] => 1000 
[msg_perm.gid] => 1000 
[msg_perm.mode] => 438 
[msg_stime] => 1279849495 
[msg_rtime] => 0 
[msg_ctime] => 1279849495 
[msg_qnum] => 1 
[msg_qbytes] => 16384 
[msg_lspid] => 2184 
[msg_lrpid] => 0 
) 
Hello,World! 

You can see that "Hello,World!" has been successfully read from the message queue. string
Here are the main functions in the sample code:
 
ftok ( string $pathname , string $proj ) 
 The explanation given in the manual is: Convert a pathname and a project identifier to a System V IPC key . The key value returned by this function is unique linux A message queue in the system. You need to call this function before you can get a reference to the message queue.  
msg_get_queue ( int $key [, int $perms ] ) 
msg_get_queue() A reference to a message queue is returned based on the incoming key value. if linux There is no message queue corresponding to the key value in the system, msg_get_queue() A new message queue will be created. The second argument to the function needs to be passed in int Value, as the permission value for the newly created message queue, defaults to 0666 . This permission value is associated with linux The command chmod The value used in linux Everything in the system is a file.  
msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize [, bool $blocking [, int &$errorcode ]]] ) 
 As the name implies, this function is used to write data to a message queue.  
msg_stat_queue ( resource $queue ) 
 This function returns the metadata of the message queue. The information in the message queue metadata is complete, including the number of messages to be read in the message queue and the process that finally reads and writes to the queue ID And so on. Sample code in the first 8 Line calls to this function return the number of messages in the array to be read from the queue msg_qnum A value of 0 .  
msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize [, int $flags [, int &$errorcode ]]] ) 
msg_receive Used to read the data in the message queue.  
msg_remove_queue ( resource $queue ) 
msg_remove_queue Used to destroy a queue.  

The example code _1 just shows you how PHP works with message queue functions. The following code details the interprocess communication scenario
 
<?php 
$message_queue_key = ftok(__FILE__, 'a'); 
$message_queue = msg_get_queue($message_queue_key, 0666); 
$pids = array(); 
for ($i = 0; $i < 5; $i++) { 
//Create child process
$pids[$i] = pcntl_fork(); 
if ($pids[$i]) { 
echo "No.$i child process was created, the pid is $pids[$i]rn"; 
} elseif ($pids[$i] == 0) { 
$pid = posix_getpid(); 
echo "process.$pid is writing nowrn"; 
msg_send($message_queue, 1, "this is process.$pid's datarn"); 
posix_kill($pid, SIGTERM); 
} 
} 
do { 
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT); 
echo $message; 
//You need to determine if the queue is empty, and if so, exit
//break; 
} while(true) 
?> 

The running result is:
 
No.0 child process was created, the pid is 5249 
No.1 child process was created, the pid is 5250 
No.2 child process was created, the pid is 5251 
No.3 child process was created, the pid is 5252 
No.4 child process was created, the pid is 5253 
process.5251 is writing now 
this is process.5251's data 
process.5253 is writing now 
process.5252 is writing now 
process.5250 is writing now 
this is process.5253's data 
this is process.5252's data 
this is process.5250's data 
process.5249 is writing now 
this is process.5249's data 

The result of this program will be different from time to time, which just shows the asynchrony of multiple processes. The FIFO feature of the message queue can also be seen from the results.
That's what I learned from my research. The next step is to explore how PHP USES signals, sockets, and so on to communicate between processes.

Related articles: