PHP 并发编程基础和实践

随着互联网的普及,网民越来越多,这就会造成随便的一个活动,就有可能面临高并发带来的性能问题。而 PHP 是单进程的,很容易造成性能瓶颈,所以 PHP 的并发编程实践显得格外重要。如果想要真正理解并发,我们需要一些基础的理论知识。

进程、线程与协程

进程

  • 是计算机中程序关于某数据集合上的一次运行活动
  • 是系统进行资源分配和调度的基本单位
  • 是操作系统结构的基础
  • 是一个“执行中的程序”

进程的三态模型

多道程序系统中,进程在处理机上交替运行,状态不断发生变化。

三态模型

  • 运行

    • 当一个进程在处理机上运行时,则称该进程处于运行状态
    • 在没有其他进程可以运行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程
  • 就绪

    • 当一个进程获得了除处理机以外的一切所需资源,一旦得到处理机即可运行,则称次进程处于就绪状态
    • 就绪状态可以按多个优先级来划分队列。如当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当一个进程由 I/O 操作完成而进入就绪状态时,排入高优先级队列
  • 阻塞

    • 又称等待或睡眠状态,一个进程正等待某一件事情发生(如请求 I/O,等待其完成)而暂时停止运行,这是即使把处理机分配给该进程也无法运行,故称该进程处于阻塞状态

进程的五态模型

对于一个实际的系统,进程的状态及其转换更为复杂。

五态模型

  • 新建态

    • 进程刚刚被创建时没有提交的状态,并等待系统获取(创建进程的)所有必要信息
  • 活跃就绪/静止就绪

    • 活跃就绪:进程在主存并且处于可被调度的状态
    • 静止(挂起)就绪:进程被对换到辅存时的就绪状态,是不能被直接调度的状态,只有当主存中没有活跃就绪进程,或者静止就绪进程具有更高优先级,系统将把静止就绪进程调回主存并转换为活跃就绪状态
  • 运行

    • 进程在处理机上运行时,则称该进程处于运行状态
  • 活跃阻塞/静止阻塞

    • 活跃阻塞:进程已在主存,一旦等待的事件完成便进入活跃就绪状态
    • 静止阻塞:进程对换到辅存时的阻塞状态,一旦等待的事件完成便进入静止就绪状态
  • 终止态

    • 进程已经结束运行,回收除进程控制块之外的其他资源,并让其他资源从进程控制块中收集有关信息

线程

由于用户的并发请求,为每一个请求都创建一个进程显然行不通,这会造成极大的资源开销,同时系统响应用户请求会很慢。由此,在操作系统中,线程的概念便被引入进来了。

线程的概念:

  • 线程被称为轻量级进程,是程序执行流的最小单元
  • 线程是进程的一个实体,是被系统独立调度和分配的基本单位
  • 线程自己不拥有系统资源,只拥有极少的在运行中必不可少的资源,他可以与同属于一个进程的其他线程共享进程的所有资源
  • 一个线程可以创建和撤销另一个线程,同一进程中的多个线程可以并发执行
  • 线程是程序中一个单一的顺序控制流程

每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身

协程

一种用户态的轻量级线程,协程的调度完全由用户控制。多个携程任务有点类似多线程,但协程的特点在于是一个线程执行。

和多线程比,协程的优势:

  • 最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显
  • 第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多

更多关于协程的知识:廖雪峰-协程

进程 VS 线程

  • 不同点
    • 线程是进程内的一个执行单元,每个进程只要包含一个线程,所有线程共享进程的地址空间,而进程有自己独立的地址空间
    • 进程是资源分配和拥有的单位,同一进程内的线程共享进程资源
    • 线程是处理机调度的基本单位,而进程是资源分配和拥有的基本单位
  • 相同点
    • 都可以并发执行

协程 VS 线程

  • 一个线程可以拥有多个协程,一个进程也可以单独拥有多个协程
  • 进程和线程是同步机制,而协程是异步机制
  • 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上次调用的状态

多进程和多线程

  • 多进程
    同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态,称为多进程

  • 多线程
    在单个程序中,同时运行多个线程完成不同的工作,称为多线程

  • 类比生活中的例子

    • 单进程单线程:一个人在一张桌子上吃饭
    • 单进程多线程:多个人在一张桌子上吃饭
    • 多进程单线程:多个人,每个人在自己桌子上吃饭
    • 多进程多线程:多群人,每群人在自己桌子上吃饭

编程模型

一般来说,程序任务主要分为两种,一种是同步阻塞模型,另一种是异步非阻塞模型。

同步阻塞模型

如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。

缺点:

  • 这种模型严重依赖进程的数量解决问题
  • 启用大量的进程会带来额外的进程调度消耗

异步非阻塞模型

现在各种高并发异步 I/O 的服务器程序都是基于 epoll 实现的。I/O 复用异步非阻塞模型程序使用经典的 Reactor 模型,Reactor 是反应堆的意思,它本身不处理任何数据的收发,只是监测一个 socket 句柄的事件变化。

Reactor模型

Reactor 模型简介

  • add:添加一个 socket 到 Reactor
  • set:修改 socket 对应的事件,如可读可写
  • del:从 Reactor 中移除
  • callback:事件发生后回调指定的函数

Reactor 模型应用

  • Nginx:多线程 Reactor 模型
  • Swoole:多线程 Reactor 模型 + 多进程 Worker

PHP 并发编程实践

PHP 的 Swoole 扩展

Swoole 是 PHP 的异步、并行、高性能网络通信引擎,使用纯 C 语言编写,提供了 PHP 语言的:

  • 异步多线程服务器
  • 异步 TCP/UDP 网络客户端
  • 异步 MySQL
  • 异步 Redis
  • 数据库连接池
  • AsyncTask
  • 消息队列
  • 毫秒定时器
  • 异步文件读写
  • 异步 DNS 查询

消息队列

消息队列产品

  • Kafka
  • ActiveMQ
  • ZeroMQ
  • RabbitMQ
  • Redis

接口的并发请求

curl_multi_init

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值