服务报价 | 域名主机 | 网络营销 | 软件工具| [加入收藏]
 热线电话: #
当前位置: 主页 > php教程 > php教程 >

没有event loop的PHP多进程多线程

时间:2016-01-03 21:12来源:未知 作者:最模板 点击:
l 多线程,克隆线程 三,proc_open,popen也是利用httpd来实现多进程 ?php $proc=proc_open(echo foo, array( array(pipe,r), array(pipe,w), array(pipe,w) ), $pipes); print stream_get_contents($pipes[1]); ? 检测方法可以和
javascript是单线程脚本语言,所以有了event loop机制,但是php真的有多进程,多线程吗?
 
一,php利用socket来实现多线程
在服务器端有一个程序,与多个客户端程序通讯,其中主线程有一个socket绑定在一个固定端口上,负责监听客户端的 Socket信息。每当启动一个客户端程序,客户端发送来一个socket连接请求,server端就新开启一个线程,并在其中创建一个socket与该 客户端的socket通讯,直到客户端程序关闭,结束该线程。
 
<?php  
function thread($count=1) {  
 for($i=0;$i<$count;$i++){  
 $fp=fsockopen($_SERVER['HTTP_HOST'],80);  
 fputs($fp,"GET http://localhost/aaaa/getset.php\r\n");  
 fclose($fp);  
 soc_log('socket',Date('d h:i:s', mktime()) . (double)microtime());  
 }  
}  
  
 function soc_log($script,$start_time)  
 {  
 $fp = fopen($script.".log", 'a+');  
 fputs($fp, 'start time is ' . $start_time. "\n");  
 fclose($fp);  
 }  
  
 thread(5);  
 for($j=0;$j<5;$j++){  
 soc_log('nosocket',Date('d h:i:s', mktime()) . (double)microtime());  
 }  
  
?>  
根据socket的这种特性,写了一小段代码,并且记录下每次连接socket的时间,以及不通过socket来,记录执行时间,我的本意是,如果php真的能实现多线程的话,socket.log和nosocket.log里面记录的时间是相同的。我用压力测试工具测试一下,这样做是为了尽量做到并发,这样log出现相同的时间可能性更大。
[zhangy@BlackGhost ~]$ /usr/local/bin/webbench -c 10 -t 5 http://localhost/aaaa/socket.php
我查看一下二个log文件里面根本没有相同的,感觉好像是错开的。后来我仔细想了想,访问socket.php这个页面时,里面还是通过php来执行程序,所以根本不可能向几个线程同时,发送请求,肯定有先,有后。
二,pcntl_fork利用httpd来实现多进程
开始的时候,我并不知道pcntl_fork是怎么利用什么来实现多进程的,无意中发现他是增加了httpd的进程数来实现多进程的。我汗。举例说明
 
<?php  
$pid = pcntl_fork();  
echo "$pid<br>";  
if ($pid == -1) {  
 throw new Exception('could not fork');  
} else if ($pid) {  
 //we are the parent  
 echo 'Forked successfully';  
 flush();  
//    posix_kill(posix_getpid(), SIGTERM);  
 exit;  
} else {  
//    posix_kill(posix_getpid(), SIGTERM);  
 exit;  
}  
?>  
1,启动一下你的apache然后执行一下以下这个命令:
[root@BlackGhost pcntl]# ps -e|grep httpd |wc -l
10
也就是现在有10httpd进程
2,多执行一下上面的程序,然后在执行以下命令
[root@BlackGhost pcntl]# ps -e|grep httpd |wc -l
18
你会发现竟然多出来一些httpd进程,并且页面可以输出每个httpd的pid,如果不进行kill的话,随着请求的增加,httpd会不断的增加,直到死机为止。还有启动进程,和关闭进程,都要时间,这样频繁的开启,和关闭进程不见得能提高多少性能。还有pcntl只能用于php-cli,这就不用多说了,php-cgi里面根本没有httpd这个东西。如果你装apache的进修没有--enable-pcntl的话,可以用phpize来添加pcntl模块,请参考phpize增加php模块
其实也可以用top命令来看
[root@BlackGhost pcntl]# top  
  
top - 20:52:03 up  1:52,  1 user,  load average: 0.08, 0.09, 0.07  
Tasks: 122 total,   2 running, 120 sleeping,   0 stopped,   0 zombie  
Cpu(s): 10.6%us,  7.0%sy,  0.0%ni, 82.5%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st  
Mem:   1027516k total,   889636k used,   137880k free,   139388k buffers  
Swap:        0k total,        0k used,        0k free,   257376k cached  
  
 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND  
 4468 zhangy    20   0  436m 225m  29m S   12 22.5  12:12.52 firefox-bin  
 4387 root      19  -1 59916  46m  12m S    5  4.7   3:19.78 X  
 8012 zhangy    20   0 53256 9040 2792 R    4  0.9   0:01.04 httpd  
 8030 zhangy    20   0 53256 8740 2492 S    4  0.9   0:01.90 httpd  
 8010 zhangy    20   0 53128 8772 2736 R    3  0.9   0:37.98 httpd  
 4541 zhangy    20   0 70540  29m  11m S    2  3.0   2:43.99 mplayer  
 4425 zhangy    20   0 56296  15m 9316 R    2  1.5   1:42.84 sakura  
 4399 zhangy    20   0 15680 9.9m 3032 S    1  1.0   1:27.18 python  
 4422 zhangy    20   0 46212  20m  12m S    0  2.1   0:38.40 python  
 8068 root      20   0  2348 1036  812 R    0  0.1   0:00.04 top  
 1 root      20   0  1704  616  552 S    0  0.1   0:00.81 init  
 2 root      20   0     0    0    0 S    0  0.0   0:00.00 kthreadd  
 3 root      RT   0     0    0    0 S    0  0.0   0:00.00 migration/0  
 4 root      20   0     0    0    0 S    0  0.0   0:00.11 ksoftirqd/0  
关于S这一列,下面有一些注释
R    正在运行,或在队列中的进程
S    处于休眠状态
T    停止或被追踪
Z    僵尸进程
W    进入内存交换(从内核2.6开始无效)
X    死掉的进程
<    高优先级
N    低优先级
L    有些页被锁进内存
s    包含子进程
+    位于后台的进程组;
l    多线程,克隆线程
三,proc_open,popen也是利用httpd来实现多进程
 
<?php  
$proc=proc_open("echo foo",  
 array(  
 array("pipe","r"),  
 array("pipe","w"),  
 array("pipe","w")  
 ),  
 $pipes);  
print stream_get_contents($pipes[1]);  
?>  
检测方法可以和pcntl_fork一样,看一下httpd进程数的变化,popen和proc_open差不多就不多说了。
 
(责任编辑:最模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容