stream_set_blocking ($resource, $flag); $flag 取值为0或1 数组
0是非阻塞,1是阻塞 网络
阻塞的意义是什么呢? 并发
某个函数读取一个网络流,当没有未读取字节的时候,程序该怎么办? 异步
是一直等待,直到下一个未读取的字节的出现,仍是当即告诉调用者当前没有新内容? 函数
前者是阻塞的,后者是非阻塞的。 spa
阻塞的好处是,排除其它非正常因素,阻塞的是按顺序执行的同步的读取。 server
借用小说里的说法就是“神刀出鞘,无血不归”。在读到新内容以前,它不会往下走,什么别的事情都不作。 队列
而非阻塞,由于没必要等待内容,因此能异步的执行,如今读到读不到都不要紧,执行读取操做后马上就继续往下作别的事情。 get
若是你不放心,能够过必定的时间再来检查执行的结果。以前我写过一个用popen pclose来让程序并发执行的例子。 同步
当时的遗憾就是调用以后无论,因此无法知道程序是否执行成功了。如今popen以后设定为非阻塞模式,就能够建立一个数组做为任务池。
使用一个while(1)的“死循环”来检查当前任务池中各个任务的状态,有老任务执行完毕时,$status = stream_get_meta_data($resource);
状态值$status['eof']为真,就表示那个任务执行完毕了。我本次实现的程序功能比较单一,只须要知道它执行完毕就能够了。若是你的任务有多种结果,那就继续分析读取到的内容吧。发现有任务执行完毕,从任务池中剔除该任务,若是任务队列中还有未作的任务,就把新任务从队列中移到任务池中执行。
说的比较啰嗦,若是你用过网络蚂蚁或网际快车之类的下载软件,你会发现我讲的这些其实就是它们的工做原理。
PHP函数stream_set_timeout(Stream Functions)做用于读取流时的时间控制。fsockopen函数的timeout只管建立链接时的超时,对于链接后读取流时的超时,则须要用到 stream_set_timeout函数。因为国内的网络环境不是很稳定,尤为是链接国外的时候,不想程序出现Fatal error: Maximum execution time of 30 seconds exceeded in …的错误,该函数尤为有用。stream_set_timeout需配合stream_get_meta_data使用,若是没有timeout, stream_get_meta_data返回数组中time_out为空,反之为1,可根据此判断是否超时。另外因为PHP默认的Maximum execution time为30秒,这是一次执行周期的时间,为了避免出现上述的Fatal error,还须要设置一个总的读取流的时间,具体方法参见下面详细代码。