PHP IPC函数,shm,shmop,message——共享内存函数,消息队列,与c/c++通讯

--enable-sysvsem.  信号量,个人感觉最好是无锁无信号设计速度更快

--enable-sysvshm.  shm*函数,将php变量放入共享内存,单一id可以插入多个php变量,自动序列化,用于php之间通讯

--enable-sysvmsg. 消息队列函数,无需手动控制内存大小,php之间通讯,(应该可以与c通讯,但是应该没有现成的c端代码)

 

以上,默认是开启的。

--enable-shmop shmop共享内存操作函数,可以与c/c++通讯

 

测试了消息队列(cli模式下),感觉非常适合php之间通讯,所以不研究shm了

<?php  
/* 
 * class msg 
 * Use for communication between php and php; 
 * Create at: 12:08 2012/10/31 
 * Author: leixun(lein_urg@163.com) 
 * version 1 - 14:01 2012/10/31 
 */  
  
class msg{  
    private $id;  
    private $msg_id;  
    private $_serialize = true;  
  
    /** 
     * @param $_id ID 
     */  
    public function msg($_id, $_serialize = true){  
        $this->id = $_id;  
        $this->msg_id = msg_get_queue ( $_id );  
        $this->_serialize = $_serialize;  
        if ($this->msg_id === false) {  
            die(basename(__FILE__).'->'.__LINE__.': Unable to create message quee');  
        }  
    }  
  
    /** 
     * @data data to send 
     * @type message type 
     */  
    public function send( $data, $type = 1, $blocking = false )  
    {  
        if (!msg_send ($this->msg_id, $type, $data, $this->_serialize, $blocking, $msg_err))  
        {  
            return "Msg not sent because $msg_err\n";  
        }  
        return true;  
    }  
  
    /** 
     * @param $type message type 
     * @param $maxsize The maximum size of message to be accepted, 
     */  
    public function receive($type = 1 , $maxsize = 1024 )  
    {  
        $rs = msg_receive ( $this->msg_id , $type ,  $type , $maxsize , $message , $this->_serialize, MSG_IPC_NOWAIT , $errorcode);  
        if($rs)  
            return $message;  
        else  
            return false;  
    }  
  
    public function remove()  
    {  
        msg_remove_queue($this->msg_id);  
    }     
} 

<?php  
//写消息的进程  
define('base_path' , dirname(__FILE__));  
include(base_path.'/msg.php');  
  
$arr = array(999999999,999999999,999,999);  
$block_size = strlen(serialize($arr));  
  
$count = 1000;  
  
$msg = new msg(1);  
  
  
while(1){  
    $arr = array(rand(1,999999999),rand(1,999999999),999,999);  
    $msg->send($arr);  
    sleep(rand(3,5));  
}  
echo 'Done'; 

<?php  
//读消息的进程  
define('base_path' , dirname(__FILE__));  
include(base_path.'/msg.php');  
  
$arr = array(999999999,999999999,999,999);  
$block_size = strlen(serialize($arr));  
  
$count = 1000;  
  
$msg = new msg(1);  
  
  
while(1){  
  
    var_dump($msg->receive());  
    sleep(4);  
}  

我查阅资料,发现c也有消息队列函数,令我很兴奋,找了一个c的列子,c本身消息队列收发成功了。然后我尝试php和c对发,因为c发送的的是c的结构体struct,所以我寻求php生成c结构体struct的办法,我用了pack,搜索了pack,或者php struct,出来的文章都是同一篇,完全不正确的,经过记录c发送的数据,然后将我用php pack的数据做对比,发现数据是一模一样的,但是,发送给c,c无法解析。还好我有点儿php扩展基础,找到php的消息函数,一看:我失望了,php的消息函数发送的struct是固定的,一个int和一个char[1],经过一番测试之后,能将一个数字和一个字符串发送给c了

PHP代码:

$id =  msg_get_queue ( 1 );  
    if (!msg_send ($id, 317, "sdsadsdsds", false, true, $msg_err))  
    {  
        return "Msg not sent because $msg_err\n";  
    }  

c代码:

#include <stdio.h>  
#include <stdlib.h>  
#include <fcntl.h>  
#include <string.h>  
#include <unistd.h>  
#include <sys/types.h>  
#include <sys/ipc.h>  
#include <sys/msg.h>  
#define MAX_TEXT 512  
#define BUFSIZE BUFSIZ  
  
struct msg_st {  
    long mtype;  
    char mtext[1];  
};  
  
void logst(struct msg_st some_data);  
  
int main(int argc,char **argv)  
{  
        while(1){  
              
            int msgid1;  
            struct msg_st some_data1;  
            int msg_to_recevie = 0;  
            if((msgid1= msgget((key_t)1,0666|IPC_CREAT)) == -1)  
            {  
                perror("msgget");  
                exit(EXIT_FAILURE);  
            }         
            if(msgrcv(msgid1,(void *) &some_data1, BUFSIZ, msg_to_recevie , 0) == -1)  
            {  
                perror("msgrcv");  
                exit(EXIT_FAILURE);  
            }  
            printf("recevier mssage : %s, type= %d;\n", some_data1.mtext, some_data1.mtype);  
            //printf("%s, %d\n", msg_text, strlen(msg_text));  
              
            if(msgctl(msgid1,IPC_RMID,0) == -1)  
            {  
                fprintf(stderr,"msgctl(IPC_RMID) failed \n");  
                exit(EXIT_FAILURE);  
            }  
            //break;  
            sleep(1);  
        }     
      
}  

如果反之,c应该也能发送一个整型和一个字符串给php,要想实现发送自定义的数据,那么就只能自己写扩展了!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值