关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » PHP »PHP代码分享:开启多进程

    PHP代码分享:开启多进程

    2015-03-03 00:00:00 出处:闫肃的博客
    分享

    下面要分享一段开启多进程的PHP代码,不多做解释,都在注释里面。

    本文实例讲述了PHP开启多进程的方法。分享给大家供大家参考。具体实现方法如下:

    < php 
     $IP='192.168.1.1';//Windows電腦的IP
     $Port='5900';        //VNC使用的Port
     $ServerPort='9999';//Linux Server對外使用的Port
     $RemoteSocket=false;//連線到VNC的Socket
     function SignalFunction($Signal){
      //這是主Process的訊息處理函數
     global $PID;//Child Process的PID
     switch ($Signal)
     {
      case SIGTRAP:
      case SIGTERM:
       //收到結束程式的Signal
       if($PID)
       {
        //送一個SIGTERM的訊號給Child告訴他趕快結束掉嘍
        posix_kill($PID,SIGTERM);
        //等待Child Process結束,避免zombie
        pcntl_wait($Status);
       }
       //關閉主Process開啟的Socket
       DestroySocket();
       exit(0); //結束主Process
       break;
      case SIGCHLD:
       /*
    當Child Process結束掉時,Child會送一個SIGCHLD訊號給Parrent
    當Parrent收到SIGCHLD,就知道Child Process已經結束嘍 ,該做一些
    結束的動作*/
       unset($PID); //將$PID清空,表示Child Process已經結束
       pcntl_wait($Status); //避免Zombie
       break;
      default:
     }
     }
     function ChildSignalFunction($Signal){
    //這是Child Process的訊息處理函數
     switch ($Signal)
     {
      case SIGTRAP:
      case SIGTERM:
    //Child Process收到結束的訊息
       DestroySocket(); //關閉Socket
       exit(0); //結束Child Process
      default:
     }
     }
     function ProcessSocket($ConnectedServerSocket){
     //Child Process Socket處理函數
     //$ConnectedServerSocket -> 外部連進來的Socket
     global $ServerSocket,$RemoteSocket,$IP,$Port;
     $ServerSocket=$ConnectedServerSocket;
     declare(ticks = 1); //這一行一定要加,不然沒辦法設定訊息處理函數。
    //設定訊息處理函數
     if(!pcntl_signal(SIGTERM, "ChildSignalFunction")) return;
     if(!pcntl_signal(SIGTRAP, "ChildSignalFunction")) return;
    //建立一個連線到VNC的Socket
     $RemoteSocket=socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
    //連線到內部的VNC
     @$RemoteConnected=socket_connect($RemoteSocket,$IP,$Port);
     if(!$RemoteConnected) return; //無法連線到VNC 結束
    //將Socket的處理設為Nonblock,避免程式被Block住
     if(!socket_set_nonblock($RemoteSocket)) return;
     if(!socket_set_nonblock($ServerSocket)) return;
     while(true)
     {
    //這邊我們採用pooling的方式去取得資料
      $NoRecvData=false;   //這個變數用來判別外部的連線是否有讀到資料
      $NoRemoteRecvData=false;//這個變數用來判別VNC連線是否有讀到資料
      @$RecvData=socket_read($ServerSocket,4096,PHP_BINARY_READ);
    //從外部連線讀取4096 bytes的資料
      @$RemoteRecvData=socket_read($RemoteSocket,4096,PHP_BINARY_READ);
    //從vnc連線連線讀取4096 bytes的資料
      if($RemoteRecvData==='')
      {
    //VNC連線中斷,該結束嘍
       echo"Remote Connection Closen";
       return;   
      }
      if($RemoteRecvData===false)
      {
    /*
    由於我們是採用nonblobk模式
    這裡的情況就是vnc連線沒有可供讀取的資料
    */
       $NoRemoteRecvData=true;
    //清除掉Last Errror
       socket_clear_error($RemoteSocket);
      }
      if($RecvData==='')
      {
    //外部連線中斷,該結束嘍
       echo"Client Connection Closen";
       return;
      }
      if($RecvData===false)
      {
    /*
    由於我們是採用nonblobk模式
    這裡的情況就是外部連線沒有可供讀取的資料
    */
       $NoRecvData=true;
    //清除掉Last Errror
       socket_clear_error($ServerSocket);
      }
      if($NoRecvData&&$NoRemoteRecvData)
      {
    //假如外部連線以及VNC連線都沒有資料可以讀取時,
    //就讓程式睡個0.1秒,避免長期佔用CPU資源
       usleep(100000);
    //睡醒後,繼續作pooling的動作讀取socket
       continue;
      }
      //Recv Data
      if(!$NoRecvData)
      {
    //外部連線讀取到資料
       while(true)
       {
    //把外部連線讀到的資料,轉送到VNC連線上
        @$WriteLen=socket_write($RemoteSocket,$RecvData);
        if($WriteLen===false)
        {
    //由於網路傳輸的問題,目前暫時無法寫入資料
    //先睡個0.1秒再繼續嘗試。
         usleep(100000);
         continue;
        }
        if($WriteLen===0)
        {
    //遠端連線中斷,程式該結束了
         echo"Remote Write Connection Closen";
         return;
        }
    //從外部連線讀取的資料,已經完全送給VNC連線時,中斷這個迴圈。
        if($WriteLen==strlen($RecvData)) break;
    //假如資料一次送不完就得拆成好幾次傳送,直到所有的資料全部送出為止
        $RecvData=substr($RecvData,$WriteLen);
       }
      }
      if(!$NoRemoteRecvData)
      {
    //這邊是從VNC連線讀取到的資料,再轉送回外部的連線
    //原理跟上面差不多不再贅述
       while(true)
       {
        @$WriteLen=socket_write($ServerSocket,$RemoteRecvData);
        if($WriteLen===false)
        {
         usleep(100000);
         continue;
        }
        if($WriteLen===0)
        {
         echo"Remote Write Connection Closen";
         return;
        }
        if($WriteLen==strlen($RemoteRecvData)) break;
        $RemoteRecvData=substr($RemoteRecvData,$WriteLen);
       }
      }
     }
     }
     function DestroySocket(){
    //用來關閉已經開啟的Socket
     global$ServerSocket,$RemoteSocket;
     if($RemoteSocket)
     {
    //假如已經開啟VNC連線
    //在Close Socket前必須將Socket shutdown不然對方不知到你已經關閉連線了
      @socket_shutdown($RemoteSocket,2);
      socket_clear_error($RemoteSocket);
    //關閉Socket
      socket_close($RemoteSocket);   
     }
    //關閉外部的連線
     @socket_shutdown($ServerSocket,2);
     socket_clear_error($ServerSocket);
     socket_close($ServerSocket);
     }
    //這裡是整個程式的開頭,程式從這邊開始執行
    //這裡首先執行一次fork
     $PID=pcntl_fork();
     if($PID==-1) die("could not fork");
    //假如$PID不為0表示這是Parrent Process
    //$PID就是Child Process
    //這是Parrent Process 自己結束掉,讓Child成為一個Daemon。
     if($PID) die("Daemon PID:$PIDn");
    //從這邊開始,就是Daemon模式在執行了
    //將目前的Process跟終端機脫離成為daemon模式
     if(!posix_setsid()) die("could not detach from terminaln");
    //設定daemon 的訊息處理函數
     declare(ticks = 1);
     if(!pcntl_signal(SIGTERM, "SignalFunction")) die("Error!!!n");
     if(!pcntl_signal(SIGTRAP, "SignalFunction")) die("Error!!!n");
     if(!pcntl_signal(SIGCHLD, "SignalFunction")) die("Error!!!n");
    //建立外部連線的Socket
     $ServerSocket=socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
    //設定外部連線監聽的IP以及Port,IP欄位設0,表示經聽所有介面的IP
     if(!socket_bind($ServerSocket,0,$ServerPort)) die("Cannot Bind Socket!n");
    //開始監聽Port
     if(!socket_listen($ServerSocket)) die("Cannot Listen!n");
    //將Socket設為nonblock模式
     if(!socket_set_nonblock($ServerSocket)) die("Cannot Set Server Socket to Block!n");
    //清空$PID變數,表示目前沒有任何的Child Process
     unset($PID);
     while(true)
     {
    //進入pooling模式,每隔1秒鐘就去檢查有沒有連線進來。
      sleep(1);
    //檢查有沒有連線進來
      @$ConnectedServerSocket=socket_accept($ServerSocket);
      if($ConnectedServerSocket!==false)
      {
    //有人連進來嘍
    //起始一個Child Process用來處理連線
       $PID=pcntl_fork();
       if($PID==-1) die("could not fork");
       if($PID) continue;//這是daemon process,繼續回去監聽。
       //這裡是Child Process開始
       //執行Socket裡函數
       ProcessSocket($ConnectedServerSocket);
      //處理完Socket後,結束掉Socket
       DestroySocket();
      //結束Child Process
       exit(0);
      }
     }

    以上就是PHP开启多进程的方法,希望对你有所帮助。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    技术热点

    如何删除自带的不常用应用为windows 7减负

    MySQL中多表删除方法

    改进的二值图像像素标记算法及程序实现

    windows 7 32位系统下手动修改磁盘属性例如M盘修改为F盘

    windows 7中怎么样在家庭组互传文件

    Linux应用集成MySQL数据库访问技巧

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。