PHP 协程实现
多进程/线程
最早的服务器端程序都是通过多进程、多线程来解决并发IO的问题。进程模型出现的最早,从Unix 系统诞生就开始有了进程的概念。最早的服务器端程序一般都是 Accept 一个客户端连接就创建一个进程,然后子进程进入循环同步阻塞地与客户端连接进行交互,收发处理数据。
多线程模式出现要晚一些,线程与进程相比更轻量,而且线程之间共享内存堆栈,所以不同的线程之间交互非常容易实现。比如实现一个聊天室,客户端连接之间可以交互,聊天室中的玩家可以任意的其他人发消息。用多线程模式实现非常简单,线程中可以直接向某一个客户端连接发送数据。而多进程模式就要用到管道、消息队列、共享内存等等统称进程间通信(IPC)复杂的技术才能实现。
最简单的多进程服务端模型
$serv = stream_socket_server(
"tcp://0.0.0.0:8000"
, $errno, $errstr)or
die
("Create server failed"
);while
(1
) {$conn = stream_socket_accept($serv);
if
(pcntl_fork() ==0
) {$request = fread($conn);
// do something
// $response = "hello world";
fwrite($response);
fclose($conn);
exit
(0
);}
}
多进程/线程模型的流程是:
创建一个
socket,绑定服务器端口(bind),监听端口(listen),在 PHP 中用
stream_socket_server
一个函数就能完成上面 3 个步骤,当然也可以使用更底层的sockets
扩展分别实现。
进入
while
循环,阻塞在
accept
操作上,等待客户端连接进入。此时程序会进入睡眠状态,直到有新的客户端发起
connect
到服务器,操作系统会唤醒此进程。accept
函数返回客户端连接的
socket
主进程在多进程模型下通过
fork(php: pcntl_fork)创建子进程,多线程模型下使用
pthread_create(php: new Thread)创建子线程。
下文如无特殊声明将使用进程同时表示进程/线程。
子进程创建成功后进入
while
循环,阻塞在
recv(php:fread)调用上,等待客户端向服务器发送数据。收到数据后服务器程序进行处理然后使用
send(php: fwrite)向客户端发送响应。长连接的服务会持续与客户端交互,而短连接服务一般收到响应就会
close。
当客户端连接关闭时,子进程退出并销毁所有资源,主进程会回收掉此子进程。
为了更好地阅读体验,请点击“阅读原文”继续阅读!
- V神(Vitalik Buterin)希望以太社区基金实现炒作
- 天津:169家重点监测企业初一实现销售收入1.7亿元
- 绽放冬奥赛场,斯洛文尼亚实现奖牌突破
- 100多年前,杭州就有了\"地铁\"!这个地方实现轨交、公交双覆盖
- 银行存款方式你懂吗?怎么实现正确理财日入上百
- 最近很容易被意外之财砸中的星座,你的发财梦终于要实现了
- 78岁天津股神曝:“三不卖七不买”,字字珠玑,背熟5句实现千万本金
- 蜜蜂养殖技术|对实现规模化养蜂的八点建议
- 依靠自身辛勤劳动实现脱贫 贫困户乐享产业红利
- Magic Leap 创始人承诺:5年内实现全息投影直播