一般情况下的php中的程序是单进程的,执行完一句再接着下一句(这里不用php的pcntl_fork()系列的函数,我的这种做法比那种好多了),就像一群很有素质的很饿的人(不吃这对饭就可能挂掉,大家都希望尽可能快的吃上这顿饭)排着队去买饭一样,必须一个买完了下一个再买,如果一个人拿了全是1角的零钱,也必须1角1角的数完了才能下一个。
在实际排队买饭中迟一下两下可能没问题,但是要在一个要给用户快速响应的系统中,如果出现这种现象就麻烦了,就像一个完整的登录操作分为好多步骤,要是按部就班的执行,要是卡在一个环节就完蛋了,这个用户就会看到loading按钮一直转啊转的……这个时候就需要一种机制来解决这个问题。
首先我们了解下php的进程间通信扩展,sysvmsg,这里要注意这个扩展只能在linux/uinux中使用,在其他平台无效,我的环境是centos6.3,安装这个扩展很简单:
yum -y install php-process
当然了前提是你已经安装了php,执行完之后在用下面的命令查看是否安装成功:
php -m | grep sysvmsg #若果看到sysvmsg说明安装成功了 #或者也可以这样 php -r 'var_dump(function_exists("msg_get_queue"))'; #若果看到true说明安装成功了
当然了,上面的命令需要把php路径加入到系统环境变量中。
这个扩展可以在进程间进行通讯,下面来看个例子。
发送,send.php
#!/usr/bin/php #上面的是我自己的php路径 <?php $ip = msg_get_queue(12340); //创建一个队列 msg_send($ip,1,"Test a message",false,false,$err);//像队列中塞一条消息
接受,receive.php
#!/usr/bin/php <?php $ip = msg_get_queue(12340); //创建消息队列,和发送的要一致,不然收不到消息 while(msg_receive($ip,0,$msgtype,512,$data,false,null,$err)){ echo "使用内存: ".memory_get_usage()."\n"; //这里看下使用了多少内存 echo "收到的消息: $data\n"; //收到的消息在这里 }
通过执行程序可以发现,发送消息和接受消息遵循队列的标准FIFO,这样我们根据这些特点就可以设计一个异步的系统。
怎么用这些特性的,这样想想,在程序执行的时候肯定会有很多操作,有些操作是必须时时执行的,而有些操作则是可以有延迟的,更有些操作本来就不重要还会花费很多时间的。
比如说记录登陆日志,记录游戏详细,这个时候我们就可以不必在那里等待程序执行完毕(等的话还会有可能出问题,当不重要操作特别多的时候就会浪费很多时间),而是直接把要操作的东西丢到队列里。
然后在后台单独开启一个进程来执行收到的消息,就像receive.php中一样,一直在那里等待,有消息来的时候他就运行,没有的时候就阻塞,这样是不是就成功解决了程序运行时非马上执行程序浪费时间的问题。