文章资讯
php和java哪个好(php多线程)
2022-09-02 16:38  浏览:9

php多线程(php和java哪个好)

  • 微博
  • Qzone
  • 微信

PHP实现reactor单线程网络模型

原创流浪剑客262021-05-08 23:12:24

在各种网络模型的文章中,我们常常能看到 reactor 网络模型。

它常常出现在很多软件与外部交互的网络部分,如:

redis使用reactor单线程网络IO模型。

kafka使用reactor多线程网络IO模型。

为什么需要使用网络IO模型

关于为什么要使用网络IO模型:大家需要理解一下用户态、内核态、阻塞、非阻塞、同步、异步、IO多路复用等知识。

简单来讲

在这里简单地讲,就是用户态程序没法直接操作网络IO设备,它需要发起系统调用,将控制权交给操作系统内核,内核将数据从网卡中读取数据,返回给用户态程序。在这个过程中用户态程序是等待还是不等待,内核处理的结果是怎样通知给用户程序,这就是网络IO模型可以作优化的地方。

根本原因

说到底就是优化CPU的执行时间片,不能让CPU闲着。

很重要

补充一点网络数据的 copy 操作不是CPU执行的,CPU只是初始化这个传输动作,具体数据的 copy 是由 DMA 设备来完成的。

PHP实现Reactor单线程网络模型

reactor单线程网络模型,使用到了IO多路复用的epoll模型,事件机制。操作系统需要安装libevent扩展,php需要安装event、sockets扩展。

测试例子

<?php$addr = "0.0.0.0";
$port = 8888;// 创建服务端 socket$listenFd = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);// 绑定$bindRe = socket_bind($listenFd, $addr, $port);if (!$bindRe) {    die("socket bind error");
}// 监听$listenRe = socket_listen($listenFd, 100);if (!$listenRe) {    die("socket listen error");
}global $eventArr, $eventBase;// 实例化基础事件句柄,相当与 epoll_create 操作$eventBase = new EventBase();// 绑定监听句柄,到基础事件句柄, 相当于 epoll_ctl 操作$event = new Event($eventBase, $listenFd, Event::PERSIST | Event::READ, "ep_accept");
$event->add();// 等待句柄就绪, 相当于 epoll_wait 操作$eventBase->loop();function ep_accept($listener) {    global $eventBase, $eventArr;    if (($client = socket_accept($listener)) !== false){
        $tmp = "连接成功\n";
        socket_write($client, $tmp, strlen($tmp));        // 绑定端socket,到基础事件句柄, 相当于 epoll_ctl 操作
        $clientEvent = new Event($eventBase, $client, Event::PERSIST | Event::READ, "ep_read", $client);
        $clientEvent->add();        // event实例一定要存放在一个全局数组里面。如果去掉该行,客户端强制断开再连接,服务端无法正常收到消息
      	// 这里这一步我也不知道原因,注视掉确实会导致客户端断开
      	// 希望能看到这里的大佬,评论区告知在下原因。
      	// 欢迎交流
        $eventArr[intval($client)] = $clientEvent;
    }
}function ep_read($fd) {
    $buffer = socket_read( $fd, 250 );
    $msg = "你说:{$buffer}";
    socket_write( $fd, $msg, strlen( $msg ) );
}

启动服务

php ceshi.php

结果截图

reactor单线程网络模型

我实现的功能是客户端发什么消息,服务端将消息重新返回给客户端。

这里我开了两个客户端作测试。符合实验的预期。

我个人觉得学习是个人的事,我的文章侧重于抛出一些观点,然后用简单的例子去论证,从而引发大家的兴趣,文章之中很多都是我参考了很多资料之后最简要的说明。大家应该关注文章之中引发个人困惑的东西,然后去思考学习。