当前位置:  编程技术>php
本页文章导读:
    ▪php多线程之管道通信的例子      php多线程实现管道通信,代码如下:   <?php /* 管道通信: 1. 管道可以认为是一个队列,不同的线程都可以往里面写东西,也都可以从里面读东西。写就是 在队列末尾添加,读就是在.........
    ▪php socket多线程服务器的实例分享      php支持socket,提供了socket的所有接口,可以实现一对一的通信。 php语言不支持线程,这里模拟了一个多线程代码(基于web服务器支持多线程)。 例子: <?php /** * socket 多线程 * edit by www.........
    ▪php模拟多线程 异步执行的实例分享      在php编程中,有一种简单的方式可用于 Web 程序,即使用 fsockopen()、fputs() 来请求一个 URL, 而无需等待返回,然后在被请求的url中执行相关操作,即可看作异步执行的动作。 以下为关键代码: .........

[1]php多线程之管道通信的例子
    来源: 互联网  发布时间: 2013-12-24

php多线程实现管道通信,代码如下:
 

<?php
/*
管道通信:
1. 管道可以认为是一个队列,不同的线程都可以往里面写东西,也都可以从里面读东西。写就是
在队列末尾添加,读就是在队头删除。
 
2. 管道一般有大小,默认一般是4K,也就是内容超过4K了,你就只能读,不能往里面写了。
 
3. 默认情况下,管道写入以后,就会被阻止,直到读取他的程序读取把数据读完。而读取线程也会被阻止,
   直到有进程向管道写入数据。当然,你可以改变这样的默认属性,用stream_set_block  函数,设置成非阻断模式。
 
一个封装好的管道类。
*/
class Pipe
{
    public  $fifoPath;
    private $w_pipe;
    private $r_pipe;

    /**
     * 自动创建一个管道
     *
     * @param string $name 管道名字
     * @param int $mode  管道的权限,默认任何用户组可以读写
     */
    function __construct($name = 'pipe', $mode = 0666)
    {
        $fifoPath = "/tmp/$name." . posix_getpid();
        if (!file_exists($fifoPath)) {
            if (!posix_mkfifo($fifoPath, $mode)) {
                error("create new pipe ($name) error.");
                return false;
            }
        } else {
            error( "pipe ($name) has exit.");
            return false;
        }
        $this->fifoPath = $fifoPath;
    }
   //  写管道函数开始
   function open_write()
    {
        $this->w_pipe = fopen($this->fifoPath, 'w');
        if ($this->w_pipe == NULL) {
            error("open pipe {$this->fifoPath} for write error.");
            return false;
        }
        return true;
    }
 
    function write($data)
    {
        return fwrite($this->w_pipe, $data);
    }

    function write_all($data)
    {
        $w_pipe = fopen($this->fifoPath, 'w');
        fwrite($w_pipe, $data);
        fclose($w_pipe);
    }

    function close_write()
    {
        return fclose($this->w_pipe);
    }
/// 读管道相关函数开始
function open_read()
    {
        $this->r_pipe = fopen($this->fifoPath, 'r');
        if ($this->r_pipe == NULL) {
            error("open pipe {$this->fifoPath} for read error.");
            return false;
        }
        return true;
    }

    function read($byte = 1024)
    {
        return fread($this->r_pipe, $byte);
    }

    function read_all()
    {
        $r_pipe = fopen($this->fifoPath, 'r');
        $data = '';
        while (!feof($r_pipe)) {
            //echo "read one K\n";
            $data .= fread($r_pipe, 1024);
        }
        fclose($r_pipe);
        return $data;
    }

    function close_read()
    {
        return fclose($this->r_pipe);
    }
    /**
     * 删除管道
     *
     * @return boolean is success
     */
    function rm_pipe()
    {
        return unlink($this->fifoPath);
    }
}
/*
此类实现简单的管道通信*/
?>

有关php中多线程的实现方法,请参考如下文章:
理解 php 多线程的妙用
php 多线程抓取网页的代码分享
php多线程(不使用fork)实例分享
php多线程类的代码分享
php支持多线程下载的例子


    
[2]php socket多线程服务器的实例分享
    来源: 互联网  发布时间: 2013-12-24

php支持socket,提供了socket的所有接口,可以实现一对一的通信。
php语言不支持线程,这里模拟了一个多线程代码(基于web服务器支持多线程)。

例子:

<?php
/**
* socket 多线程
* edit by www.
*/
    function runThread()
    {
        $fp = fsockopen('localhost', 80, $errno, $errmsg);
        fputs($fp, "GET /a.php?act=brnrn");        //这里的第二个参数是HTTP协议中规定的请求头
                                //不明白的请看RFC中的定义
        fclose($fp);
    }

    function a()
    {
        $fp = fopen('result_a.log', 'w');
        fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
        fclose($fp);        
    }

    function b()
    {
        $fp = fopen('result_b.log', 'w');
        fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
        fclose($fp);        
    }
    if(!isset($_GET['act'])) $_GET['act'] = 'a';
    if($_GET['act'] == 'a')
    {
        runThread();
        a();
    }
    else if($_GET['act'] == 'b') b();
?>

说明:
以上代码,虽然实现了多线程,但这些线程的通信是网页之间的通信,有session机制,http是无状态的协议,不保存用户信息,可以用session进行变量传递,而且,还有序列号,让变量序列号存在某个文件里面或者数据库里面,都是可以实现的。

socket_create/socket_accpet返回值都是一个resource指针。
serialize() 可处理除了 resource 之外的任何类型。

对于session传递,根本不可行,传递过去之后引用计数就随着之前的页面资源的卸载而销毁了。
页面传递是根本不可能传递资源类型的。
 
总结:
1,php要实现多线程,就得靠web服务器,本身没有,但是这样就必须要实现资源指针在网页之间互传。
2,资源指针是不能实现网页之间互传的。


    
[3]php模拟多线程 异步执行的实例分享
    来源: 互联网  发布时间: 2013-12-24

在php编程中,有一种简单的方式可用于 Web 程序,即使用 fsockopen()、fputs() 来请求一个 URL, 而无需等待返回,然后在被请求的url中执行相关操作,即可看作异步执行的动作。

以下为关键代码:

代码示例:
<?php
/**
* 模拟多线程 异步执行
* edit by www.
*/
$fp = fsockopen('localhost',80,&$errno,&$errstr,5);
if(!$fp)
{
     echo "$errstr ($errno)<br />/n";
}
fputs($fp,"GET another_page.php?flag=1/r/n");
fclose($fp);
?>

以上代码向页面 another_page.php 发送完请求就不管了,用不着等待请求页面的响应数据,利用这一点即可在被请求的页面 another_page.php异步传输数据。

有这样的应用例子,每当发表了一篇新日志后需要给所有该日志的订阅者发个邮件通知,一般方式为:
日志写完 -> 点提交按钮 -> 日志插入到数据库 -> 发送邮件通知 -> 告知撰写者发布成功
作者在点提交按钮到看到成功提示之间可能会等待很常时间,基本是在等邮件发送的过程,比如连接邮件服务异常、或器缓慢或是订阅者太多。
而实际上是不管邮件发送成功与否,保证日志保存成功基本可接受的,所以等待邮件发送的过程是很不经济的,这个过程可异步来执行,并且邮件发送的结果不太关心或以日志形式记录备查。

改进后的流程就:
 

日志写完 -> 点提交按钮 -> 日志插入到数据库 ---> 告知撰写者发布成功
                                                           └ 发送邮件通知 -> [记下日志]

以上是实现代码,包含两个文件,分别是 write.php 和 sendmail.php,在 sendmail.php 用 sleep(seconds) 来模拟程序执行所使用时间。

1,write.php,执行耗时 1 秒:
 

代码示例:

<?php
function asyn_sendmail()
{
   $fp = fsockopen('localhost',80,&$errno,&$errstr,5);
   if(!$fp)
   {
      echo "$errstr ($errno)<br />/n";
   }
   sleep(1);
   fputs($fp,"GET /sendmail.php?param=1/r/n"); #请求的资源 URL 一定要写对
     fclose($fp);
    }

 echo time().'<br>';
 echo 'call asyn_sendmail<br>';
 asyn_sendmail(); //www.
 echo time().'<br>';
 ?>

2,sendmail.php,执行耗时 10 秒:
 

代码示例:
<?php
sleep(10);
fopen("C:/" . time(),  "w");
?>

通过页面访问 write.php,页面输出:
 

1272472697
call asyn_sendmail
1272472698
并且在 C:/ 生成文件:
1272472708

结果分析:
sendmail.php 至少花费 10 秒,但不会阻塞 write.php 继续往下执行,表明此过程是异步的。


    
最新技术文章:
▪PHP函数microtime()时间戳的定义与用法
▪PHP单一入口之apache配置内容
▪PHP数组排序方法总结(收藏)
▪php数组排序方法大全(脚本学堂整理奉献)
▪php数组排序的几个函数(附实例)
▪php二维数组排序(实例)
▪php根据键值对二维数组排序的小例子
▪php验证码(附截图)
▪php数组长度的获取方法(三个实例)
▪php获取数组长度的方法举例
▪判断php数组维度(php数组长度)的方法
▪php获取图片的exif信息的示例代码
▪PHP 数组key长度对性能的影响实例分析
▪php函数指定默认值的方法示例
▪php提交表单到当前页面、提交表单后页面重定...
▪php四舍五入的三种实现方法
▪php获得数组长度(元素个数)的方法
▪php日期函数的简单示例代码
▪php数学函数的简单示例代码
▪php字符串函数的简单示例代码
▪php文件下载代码(多浏览器兼容、支持中文文...
▪php实现文件下载、支持中文文件名的示例代码...
▪php文件下载(防止中文文件名乱码)的示例代码
▪解决PHP文件下载时中文文件名乱码的问题
▪php数组去重(一维、二维数组去重)的简单示例
▪php小数点后取两位的三种实现方法
▪php Redis 队列服务的简单示例
▪PHP导出excel时数字变为科学计数的解决方法
▪PHP数组根据值获取Key的简单示例
▪php数组去重的函数代码示例
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3