2015-03-05
本文实例讲述了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程序设计有所帮助。
1
CI框架连接数据库配置操作以及多数据库操作
09-05
2
asp 简单读取数据表并列出来 ASP如何快速从数据库读取大量数据
05-17
3
C语言关键字及其解释介绍 C语言32个关键字详解
04-05
4
C语言中sizeof是什么意思 c语言里sizeof怎样用法详解
04-26
5
最简单的asp登陆界面代码 asp登陆界面源代码详细介绍
04-12
6
PHP中的魔术方法 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep,
09-05
7
PHP中的(++i)前缀自增 和 (i++)后缀自增
09-05
8
PHP中include和require区别之我见
09-05
常用dos命令及语法
2014-09-27
将视频设置为Android手机开机动画的教程
2014-12-11
php递归返回值的问题
2014-09-05
如何安装PHPstorm并配置方法教程 phpstorm安装后要进行哪些配置
2017-05-03
java中的info是什么意思
2022-03-24
PHP 教程之如何使用BLOB存取图片信息实例
2014-09-05
IcePHP框架中的快速后台中的通用CRUD功能框架
2014-09-05
单片机编程好学吗?单片机初学者怎样看懂代码
2022-03-21
PHP数组函数array
2014-09-05
学ug编程如何快速入门?
2022-03-17
上古修仙最新版下载v10.2.29 安卓版
角色扮演 180.1M
下载最强NBA官方版下载v1.55.662 安卓版
体育运动 1.68G
下载逃跑吧少年官方正版手游下载v8.33.0 安卓2025手机版
动作闯关 1.33G
下载宝宝梦想小镇宝宝巴士最新版下载v9.87.00.00 安卓官方版
其它手游 95.9M
下载宝宝爱刷牙宝宝巴士教育版下载v9.87.00.00 安卓版
其它手游 148.0M
下载小玛丽捕鱼官方正版下载v5.13.0 安卓版
休闲益智 122.0M
下载小玛丽捕鱼旧版安装下载v5.10.10 安卓官方版
休闲益智 122.0M
下载原神bilibili服官方版下载v5.8.0 安卓哔哩哔哩服
其它手游 389.7M
下载天天捕鱼电玩版赢话费官方版下载v11.0 安卓版
下载
遇见龙2手游下载v1.1.157 安卓版
下载
太空杀国际版(Super Sus)下载v1.67.25.031 安卓版
下载
变形金刚地球之战官方版下载v25.1.1.381 安卓最新版
下载
极限捕鱼安卓版下载v6.47.6.0.5.4 赢话费正版
下载
极限捕鱼高爆版游戏下载v6.47.6.0.5.4 安卓暴击版
下载
极限捕鱼万炮版下载v6.47.6.0.5.4 安卓加强版
下载
极限捕鱼达人版下载v6.47.6.0.5.4 安卓版
下载