PHP超时处理全面总结(5)

发表于:2013-10-28来源:酷勤网作者:不详点击数: 标签:php
//Memcache读取数据超时(没有设置) libmemcahed源码中接口定义: LIBMEMCACHED_APIchar*memcached_get(memcached_st*ptr,constchar*key,size_tkey_length,size_t*value_length,uint32_t*flags,mem

  //Memcache读取数据超时(没有设置)

  libmemcahed源码中接口定义:

  LIBMEMCACHED_APIchar*memcached_get(memcached_st*ptr,constchar*key,size_tkey_length,size_t*value_length,uint32_t*flags,memcached_return_t*error);

  LIBMEMCACHED_APImemcached_return_tmemcached_mget(memcached_st*ptr,constchar*const*keys,constsize_t*key_length,size_tnumber_of_keys);

  从接口中可以看出在读取数据的时候,是没有超时设置的。

  延伸阅读:

  http://hi.baidu.com/chinauser/item/b30af90b23335dde73e67608

  http://libmemcached.org/libMemcached.html

  【如何实现超时】

  程序中需要有超时这种功能,比如你单独访问一个后端Socket模块,Socket模块不属于我们上面描述的任何一种的时候,它的协议也是私有的,那么这个时候可能需要自己去实现一些超时处理策略,这个时候就需要一些处理代码了。

  [PHP中超时实现]

  一、初级:最简单的超时实现 (秒级超时)

  思路很简单:链接一个后端,然后设置为非阻塞模式,如果没有连接上就一直循环,判断当前时间和超时时间之间的差异。

  phpsocket中实现原始的超时:(每次循环都当前时间去减,性能会很差,cpu占用会较高)

<?

$host="127.0.0.1";

$port="80";

$timeout=15;//timeoutinseconds

$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)

ordie("Unabletocreatesocketn");

socket_set_nonblock($socket) //务必设置为阻塞模式

ordie("Unabletosetnonblockonsocketn");

$time=time();

//循环的时候每次都减去相应值

while(!@socket_connect($socket,$host,$port))//如果没有连接上就一直死循环

{

$err=socket_last_error($socket);

if($err==115||$err==114)

{

if((time()-$time)>=$timeout)//每次都需要去判断一下是否超时了

{

socket_close($socket);

die("Connectiontimedout.n");

}

sleep(1);

continue;

}

die(socket_strerror($err)."n");

}

socket_set_block($this->socket)//还原阻塞模式

ordie("Unabletosetblockonsocketn");

?>

  二、升级:使用PHP自带异步IO去实现(毫秒级超时)

  说明:

  异步IO:异步IO的概念和同步IO相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。异步IO将比特分成小组进行传送,小组可以是8位的1个字符或更长。发送方可以在任何时刻发送这些比特组,而接收方从不知道它们会在什么时候到达。

  多路复用:复用模型是对多个IO操作进行检测,返回可操作集合,这样就可以对其进行操作了。这样就避免了阻塞IO不能随时处理各个IO和非阻塞占用系统资源的确定。

  使用socket_select()实现超时

  socket_select(...,floor($timeout),ceil($timeout*1000000));

  select的特点:能够设置到微秒级别的超时!

  使用socket_select()的超时代码(需要了解一些异步IO编程的知识去理解)

编程 调用类 编程#

<?php

$server=newServer;

$client=newClient;

for(;;){

foreach($select->can_read(0)as$socket){

if($socket==$client->socket){

//NewClientSocket

$select->add(socket_accept($client->socket));

}

else{

//there'ssomethingtoreadon$socket

}

}

}

?>

编程 异步多路复用IO & 超时连接处理类 编程

<?php

classselect{

var$sockets;

functionselect($sockets){

$this->sockets=array();

foreach($socketsas$socket){

$this->add($socket);

}

}

functionadd($add_socket){

array_push($this->sockets,$add_socket);

}

functionremove($remove_socket){

$sockets=array();

foreach($this->socketsas$socket){

if($remove_socket!=$socket)

$sockets[]=$socket;

}

$this->sockets=$sockets;

}

functioncan_read($timeout){

$read=$this->sockets;

socket_select($read,$write=NULL,$except=NULL,$timeout);

return$read;

}

functioncan_write($timeout){

$write=$this->sockets;

socket_select($read=NULL,$write,$except=NULL,$timeout);

return$write;

}

}

?>

原文转自:http://www.kuqin.com/web/20120808/324135.html