Operations in PHP for shared memory, Message Queuing

Source: Internet
Author: User

Http://www.cnblogs.com/fengwei/archive/2012/09/12/2682646.html

PHP, as a scripting program, usually has a short life cycle, such as in a Web application, where a request is a cycle of PHP running, and the end of the request is the life cycle cutoff. So when PHP is dealing with resources that need to be shared, it is common to keep shared data in a database or a file like dbm, and then share it with memory. You can choose existing tools to assist you, like memcache, or you can write your own code to access the operating system's shared memory segments.

There are two sets of functions for shared memory segments in PHP: System V IPC and shared memories. The System V IPC series functions make it easier to manipulate data without having to master the offset, length, etc. of Read and write as shared memory does, or to convert back and forth (because the shared memory function only supports data parameters in string format). However, the System V IPC series does not support Windows, so if you want to use it in a win environment, you can only choose shared Memory.

Because PHP does not support these functions by default, PHP needs to be recompiled. To use:
System v Semaphore, compile-time plus –enable-sysvsem
System v Shared memory, compile-time plus –ENABLE-SYSVSHM
System v Message Queuing, compile-time plus –enable-sysvmsg
Shared Memory, compile-time plus –ENABLE-SHMOP

Let's write a shared memory example:

<?php
$key = Ftok (__file__, ' I ');
$size = 100;
$shm _h = @shmop_open ($key, ' C ', 0644, $size);
if ($shm _h = = = False) {
echo "Shmop open failed";
Exit
}
$data = Shmop_read ($shm _h, 0, $size);
$data = Unserialize ($data);
If there is no data then write a
if (empty ($data)) {
echo "There is no data";
$data = "Imdonkey";
Even if the data is text, write is serialized
$write _size = Shmop_write ($shm _h, Serialize ($data), 0);
if ($write _size = = = False) echo "Shmop write failed!";
}
If there is, show it, then delete it.
else {
echo "Shared memory data:";
Print_r ($data);
Shmop_delete ($shm _h);
}
Shmop_close ($shm _h);
?>

Write an example of system V SHM:

$shm _key = Ftok (__file__, ' I ');
$memsize = 120;
$shm _h = Shm_attach ($shm _key, $memsize, 0644);
if ($shm _h = = = False) {
echo "Shmop open failed";
Exit
}
$var _key = 3;
$data = @shm_get_var ($shm _h, $var _key);
if (empty ($data)) {
$data = "Imdonkey";
echo "There is no data, insert $data. \ n";
Shm_put_var ($shm _h, $var _key, $data);
} else {
echo "Find data: $data \ n";
Shm_remove_var ($shm _h, $var _key);
}
Shm_detach ($shm _h);
?>

As you can see, SYSV has a separate var_key for each data, so that multiple data can be saved in the same memory area, instead of requesting another shared memory area as in Shmop, as well as the serialization interference (although the data is ultimately stored in a serialized form, But do not use the developer to manually implement).

The example is simple, but there are some areas to be aware of, whether it is Shm_attach or shmop_open, the size of the requested memory must meet the volume of the subsequent data, this volume includes the data itself after the serialization of the long, as well as PHP added a few header information. A formula for calculating the size of the memory to be applied is presented in the official PHP document, which guarantees that the requested memory is sufficient to store a specified amount of data. The formula is as follows:

When Shm_attach is first called, PHP writes a header to the shared memory
$shmHeaderSize = (Php_int_size * 4) + 8;
When Shm_put_var is called, PHP will precede the serialized data with a header
$shmVarSize = (((strlen (Serialize ($foo)) + (4 * php_int_size)/4) * 4) + 4;
$memsize = $shmHeaderSize + $shmVarSize;

Whether this formula is suitable for all situations, I'm afraid to say so, so I think it's best to use the data structure that is ready to be put into shared memory in the program, as much as possible to ensure that the data size is within a certain range.

There is also to prevent the sharing of memory is wasted, when the data is useless, call the corresponding remove method to release resources.

Introduction to shared memory and by the way, with Message Queuing messages queue (also in the System V IPC function Group), Message Queuing seems to be considered as another shared memory, except that the data is stored in a somewhat different manner. Simply put, each key corresponds to a queue, each queue can hold multiple data, the data between the first-out principle of operation. The example in the PHP documentation is a good introduction to the application of each function:

<?php
if (sizeof ($ARGV) <2) {
echo "Usage: $argv [0] stat|send|receive|remove msgtype msg [MSG] \ n";
echo "EX: $argv [0] send 1 \" This is no 1\ "\ n";
echo "$ARGV [0] receive ID \ n";
echo "$argv [0] stat \ n";
echo "$argv [0] remove \ n";
Exit
}

$MSGKey = "123456";
$seg = Msg_get_queue ($MSGKey);

Switch ($argv [1]) {
Case "Send":
Msg_send ($seg, $argv [2], $ARGV [3]);
echo "Msg_send done...\n";
Break

Case "Receive":
$stat = Msg_stat_queue ($seg);
Echo ' Messages in the queue: '. $stat [' Msg_qnum ']. " \ n ";
if ($stat [' Msg_qnum ']>0) {
Msg_receive ($seg, $argv [2], $msgtype, 1024x768, $data, True, msg_ipc_nowait);
Var_dump ($msgtype);
Var_dump ($data);
echo "\ n";
}
else {
echo "No Msg ... \ n ";
}
Break

Case "Stat":
Print_r (Msg_stat_queue ($seg));
Break

Case "Remove":
Msg_remove_queue ($SEG);
Break
}
?>

The data in the message queue is also constrained by size, and the specific constraints can be seen through Msg_stat_queue's msg_qbytes. The only small change in this code is when the message is received, msg_ipc_nowait is specified, or if the destination queue has no data, the default is to wait.

The common use of shared memory or Message Queuing involves multi-threaded/process, or cross-language data transfer. If you're sharing data between PHP scripts/processes, it's fine to be careful. If the requirements of cross-language, it is likely to encounter strange problems, hehe, I have not tried, but on the internet to see other people sent the bitterness paste, after a chance must be tested.

When debugging shared memory, semaphores, Message Queuing, you can coordinate with Linux system commands to observe data storage and semaphore, message queue resource allocation, such as IPCS, Ipcrm command.

Using PHP to work with Linux Message Queuing to complete interprocess communication

Interprocess communication is a crucial step when we develop a system that needs to run in a multi-process manner. Message Queuing is a way of communicating between processes in a Linux system.

On the concept and implementation of process communication in Linux system view: http://www.ibm.com/developerworks/cn/linux/l-ipc/

On the concept and implementation of Message Queuing in Linux system view: http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/
PHP's Sysvmsg module is a package of System V Message Queuing function families in System V IPC supported by Linux systems. We need to use the functions provided by the SYSVMSG module to communicate between processes. Let's take a look at the 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 );  //向消息队列中写 msg_send( $message_queue , 1,  "Hello,World!" );  $message_queue_status  = msg_stat_queue( $message_queue ); print_r( $message_queue_status );  //从消息队列中读 msg_receive( $message_queue , 0,  $message_type , 1024,  $message , true, MSG_IPC_NOWAIT); print_r( $message . "\r\n" );  msg_remove_queue( $message_queue );  ?>  
The result of this code operation 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!" was successfully read from the message queue String

The main functions in the sample code are listed below:

ftok ( string  $pathname , string  $proj )      手册上给出的解释是:Convert a pathname  and a project identifier to a System V IPC key。这个函数返回的键值唯一对应linux系统中一个消息队列。在获得消息队列的引用之前都需要调用这个函数。 msg_get_queue ( int  $key [, int  $perms ] )      msg_get_queue() 会根据传入的键值返回一个消息队列的引用。如果linux系统中没有消息队列与键值对应,msg_get_queue()将会创建一个新的消息队列。函数 的第二个参数需要传入一个int值,作为新创建的消息队列的权限值,默认为0666。这个权限值与linux命令 chmod 中使用的数值是同一个意思,因为在linux系统中一切皆是文件。 msg_send ( resource  $queue , int  $msgtype , mixed  $message [, bool  $serialize [, bool  $blocking [, int & $errorcode ]]] )      顾名思义,该函数用来向消息队列中写数据。 msg_stat_queue ( resource  $queue )      这个函数会返回消息队列的元数据。消息队列元数据中的信息很完整,包括了消息队列中待读取的消息数、最后读写队列的进程ID等。示例代码在第8行调用该函数返回的数组中队列中待读取的消息数msg_qnum值为0。 msg_receive ( resource  $queue , int  $desiredmsgtype , int & $msgtype , int  $maxsize , mixed & $message [, bool $unserialize [, int  $flags [, int & $errorcode ]]] )      msg_receive用于读取消息队列中的数据。 msg_remove_queue ( resource  $queue )      msg_remove_queue用于销毁一个队列。
The example code _1 just shows the application of the PHP operation Message Queuing function. The following code specifically describes the scenario for interprocess communication
<?php  $message_queue_key  ftok ( __FILE__ ‘a‘ ); $message_queue  = msg_get_queue( $message_queue_key , 0666);  $pids  array (); for  ( $i  = 0;   $i  < 5;  $i ++) {          //创建子进程          $pids [ $i ] = pcntl_fork();           if  ( $pids [ $i ]) {                  echo  "No.$i child process was created, the pid is $pids[$i]\r\n" ;          elseif  ( $pids [ $i ] == 0) {                  $pid  = posix_getpid();                  echo  "process.$pid is writing now\r\n" ;                   msg_send( $message_queue , 1,  "this is process.$pid‘s data\r\n" );                  posix_kill( $pid , SIGTERM);          } }  do  {          msg_receive( $message_queue , 0,  $message_type , 1024,  $message , true, MSG_IPC_NOWAIT);          echo  $message ;           //需要判断队列是否为空,如果为空就退出          //break; while (true)  ?>
The result of the operation 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

This program will run differently each time, which illustrates the asynchronous nature of multiple processes. The Message Queuing FIFO feature can also be seen from the results.

This is a little bit of my experience. The next step is to study how PHP uses signals, sockets, and so on for interprocess communication.

Operations in PHP for shared memory, Message Queuing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.