swoole笔记

发布时间:2021-05-23 23:53:32 阅读:(208)

    协程

    • 什么是协程?协程与线程的区别?

    协程可以简单理解为线程,只不过这个线程是用户态的,不需要操作系统参与,创建销毁和切换的成本非常低。从技术的角度来说,“协程就是可以暂停执行的函数”。

    协程是组织好的代码流程,线程是被分割的CPU资源,协程需要线程来承载运行,线程是协程的资源

    • 什么是协程容器

    使用 Coroutine::creatego(前一个方法的别名)方法创建协程,在创建的协程中才能使用协程 API,而协程必须创建在协程容器里面,参考协程容器。

    协程调度

    决定让CPU执行哪个协程的代码决断过程就是协程调度

    1. 在执行某个协程代码的过程中遇到了Co::sleep()或者产生了网络 IO ,如数据库查询等,Swoole 就会把这个连接的fd 防盗 EventLoop 中。
    2. 让出这个协程的CPU给其他协程使用,即yield 挂起
    3. 等待MySQL返回数据后继续执行这个协程,即resume恢复

    高性能共享内存 Table

    由于 PHP 语言不支持多线程,因此 Swoole 使用多进程模式,在多进程模式下存在进程内存隔离,在工作进程内修改 global 全局变量和超全局变量时,在其他进程是无效的。

    • 设置 worker_num=1 时,不存在进程隔离,可以使用全局变量保存数据

    服务器(协程)

    异步风格的服务器无法保证事件的顺序,例如需要先连接后接收的TCP服务

    • tips:可以动态的开启关闭服务,异步风格的服务在 start() 被调用之后就什么也干不了了,而协程风格的可以动态开启关闭服务。

      缺点:
    • 协程风格的服务不会自动创建多个进程,需要配合 Process\Pool 模块使用才能利用多核。

    • 协程风格服务其实是对 Co\Socket 模块的封装,所以用协程风格的需要对socket 编程有一定经验。
    • 目前封装层级没有异步风格服务器那么高,有些东西需要自己手动实现,比如 reload 功能需要自己监听信号来做逻辑。

      TCP服务器

    Swoole\Coroutine\Server 是一个完全<u>协程化</u>的类,用于创建协程 TCP 服务器,支持 TCP 和 unixSocket 类型。

    一键协程化

    • 什么是HOOK

    这里的HOOK类似于函数库,使用了HOOK,就可以在协程中直接使用该HOOK下的方法

    3ff0fe3ad5ff047d567ca74201359595.png

    协程编程须知

    编程范式
    • 协程内部禁止使用全局变量
    • 协程使用 use 关键字引入外部变量到当前作用域禁止使用引用
    • 协程之间通讯必须使用 channel
    • 禁止使用exit退出脚本
    异常处理

    协程编程中可直接使用 try/catch处理异常。但必须在协程内捕获,不得跨协程捕获异常。

    严重错误

    多协程共用一个连接

    与同步阻塞程序不同,协程是并发处理请求的,因此同一时间可能会有很多个请求在并行处理,一旦共用客户端连接,就会导致不同协程之间发生数据错乱。

    使用类静态变量/全局变量保存上下文

    多个协程是并发执行的,因此不能使用类静态变量 / 全局变量保存协程上下文内容。
    使用局部变量是安全的,因为局部变量的值会自动保存在协程栈中,其他协程访问不到协程的局部变量。

    正确方案:使用Context管理上下文

    可以使用一个Context类来管理协程上下文,在Context类中,使用Coroutine::getUid获取当前协程的ID,然后隔离不同协程之间的全局变量,协程退出时清理上下文数据

    杂项

    守护进程

    就是后台运行的进程,详细来说就是脱离父进程的子进程,随后该子进程被1号进程接收