一,php利用socket来实现多线程
在服务器端有一个程序,与多个客户端程序通讯,其中主线程有一个socket绑定在一个固定端口上,负责监听客户端的 Socket信息。每当启动一个客户端程序,客户端发送来一个socket连接请求,server端就新开启一个线程,并在其中创建一个socket与该 客户端的socket通讯,直到客户端程序关闭,结束该线程。
根据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差不多就不多说了。
本文分享自 交互设计前端开发与后端程序设计 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!