@PHP多进程/线程的一点思索
探索PHP多进程/线程
前言
很多PHP多进程与线程的概念比较薄弱,包括我自己也是,所以想着写一篇探索一些相关知识,不过这里只是探讨,不建议去用,如果需要使用多进程PHP,多线程相关建议使用SWOOLE,以后我会多探讨一些SWOOLE的知识。
为什么要研究多进程/线程
- 可以优化程序性能(并行处理,并发);
- 很多语言与软件采取多进程多线程,可以方便理解;
- 编写更多适合不同业务的代码;
多进程的好处
- 每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;
- 通过增加CPU扩充性能;
- 减少线程加锁/解锁的影响,极大提高性能;
- 每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大;
- 顺序程序的特点:具有封闭性和可再现性;
多线程的好处
- 相比进程可以说减少很多性能开销;
- 通过增加CPU扩充性能;
- 一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便;
- 使多CPU系统更加有效,让不同的线程运行到不同的CPU上面;
- 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程;
多进程/线程缺点(主要的)
- 不论是开多进程与多线程都会对系统造成一定负担;
- 增加逻辑复杂度,使代码不好控制;
最简单的PHP多进程服务端模型
$serv = stream_socket_server("tcp://0.0.0.0:8080", $errno, $errstr)
or die("Create server failed");
while(1) {
$conn = stream_socket_accept($serv);
if (pcntl_fork() == 0) {
$request = fread($conn);
// handle logic
fwrite($response);
fclose($conn);
exit(0);
}
}
多进程/线程模型的流程是:create->bind->listen->accept->recv->send->close
问题是这种模式进程创建和销毁的开销很大。所以上面的模式没办法应用于业务频繁的场景。
优化后的
$serv = stream_socket_server("tcp://0.0.0.0:8080", $errno, $errstr)
or die("Create server failed");
for($i = 0; $i < 8; $i++) {
if (pcntl_fork() == 0) {
while(true) {
$conn = stream_socket_accept($serv);
if ($conn == false) continue;
// handle logic
$request = fread($conn);
fwrite($response);
fclose($conn);
}
exit(0);
}
}