目录

并发

基本概念

PHP并发模型

多进程

基本概念

进程

多进程

并发多任务

任务调度

PHP实现多进程

PCNTL

PHP-FPM

Swoole

多线程

基本概念

线程

多线程

PHP实现多线程

异步处理

分布式系统


并发

基本概念

并发又被称为共行,是指同时段内处理多个任务。现代计算机系统能够在同一时段内以进程的形式,将多个程序加载到存储器中,由于CPU的时分复用(时间片轮转的抢占式调度方式),能让人产生多个任务在同一个CPU上同时执行的错觉。

注意并发是指逻辑上同时发生,而并行则是指物理上同时发生。

PHP并发模型

PHP并发模型可以分为多进程模式和多线程模式,具体使用的是哪一种,得看PHP使用的是哪个SAPI(服务器应用程序编程接口)。例如Apache中可能采用多进程模型,也可能采用多线程模型。

Nginx是非阻塞IO&IO复用模型,通过操作系统提供的类似epoll(Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量连接活跃时的系统CPU利用率)功能,可以在一个线程里处理多个客户端的请求。Ngnix每个进程里只有一个线程,但这一个线程可以服务多个客户端。

PHP-FPM是阻塞的单线程模型,PHP-FPM每个进程里只有一个线程,一个进程同时只能服务一个客户端。

注意很多Linux程序都倾向于使用进程而不是线程,因为Linux下相对来说创建进程的开销比较小,而Linux的线程功能又不是很强大。

多进程

基本概念

进程

  1. 进程(process)可理解为是程序运行时的一个实例。进程有两个特性,一是资源的所有权,二是调度执行(指令集)。
  2. 从内核的角度来看,进程是分配系统资源的基本单位。
  3. 一个进程至少包含一个线程(主线程)。如何调度进程和线程,由操作系统决定。

多进程

  1. 子进程结束后,系统内核会负责回收资源。
  2. 使用多进程比使用多线程更加稳定,因为子进程的异常退出不会导致整个进程退出,父进程还有机会重建流程。
  3. 一个常驻主进程,只负责任务分发,这样可让逻辑显得很清晰。
  4. 进程间通信IPC也可以实现数据共享,同样需要加锁,会有同步、死锁问题。
  5. 使用多进程消息队列,可以采用子进程抢夺队列模式,性能很好。

并发多任务

在实际编程中,实现并发多任务的方式主要有三种:

  1. . 多进程模式。
  2. . 多线程模式。
  3. . 多进程+多线程 模式。

真正的并行多任务只能在多核CPU上实现。由于任务数量会远远超出CPU的核数,所以操作系统会自动把多个任务轮流调度到每个核心上完成。

任务调度

大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行,任务执行的一小段时间叫做时间片。由于CPU的执行效率高,时间片非常短,在各个任务之间快速地切换,保障了一个大的时间段里多个任务都能运行(并发)。

PHP实现多进程

PCNTL

安装运行

php中通过添加PCNTL拓展方式实现多进程需要安装两个模块:pcntl和posix。

在php中进程控制支持(pcntl)默认是关闭的,所以需要使用--enable-pcntl配置选项重新编译php的CGI或者CLI版本以打开进程控制支持。而posix拓展是默认启用的。

centos 操作系统下 运行 yum -y install php-process 即可安装pcntl和posix拓展。

检测是否安装成功的方法:

php -m 查看php在cli模式下已安装的拓展列表。

也可以通过 php -m|grep pcntl 和 php -m|grep posix 来查看。

注意pcntl的多进程实现只能在cli(Command Line Interface,命令行接口)模式下,在Web服务器环境下,会出现难以预期的结果。

重要函数

pcntl_fork():int

在当前进程当前位置产生分支(子进程),父进程和子进程都是从fork(分岔口)的位置继续往下执行,不同的是父进程执行过程中,得到的pcntl_fork函数返回值为子进程号(>0),而子进程得到的pcntl_fork函数返回值为0。pcntl_fork()创建子进程失败时返回-1,不会创建一个子进程,还会引发一个php错误。

pcntl_signal(int $signo,callback $handler,bool $restart_syscalls=true):bool

注册一个信号处理回调函数,可以捕获子进程结束时发出的信号。

pcntl_wait(int &$status,int $options=0,array &$rusage=?):int

挂起当前进程的执行直到子进程退出,或者直到传递了一个信号,其动作是终止当前进程或调用信号处理函数。如果调用此函数时子进程已经退出(俗称“僵尸”进程),则此函数立刻返回,释放子进程使用的任何系统资源。

pcntl_waitpid(int $pid,int &$status,int $options=0):int

$pid值为-1时等同于pcntl_wait函数。pcntl_wait和pcntl_waitpid函数的一大作用就是避免出现父进程还没回收完子进程就早早退出的情况。

注意事项

如果是在循环中创建了子进程,那么子进程最后要exit,避免子进程进入循环。

PHP-FPM

相关概念

cgi:通用网关接口。

php-cgi:php解释器。

Fastcgi:用来提高cgi程序(如php-cgi)性能的方案/协议。

php-fpm可以理解为是实现了Fastcgi的程序,官方对于fpm的解释是Fastcgi Process Manager(Fastcgi进程管理器)。

简单了解

php-fpm提供了更好的php进程管理方式,可以有效控制内存和进程,可以平滑重载php配置。

php-fpm可以通过php-fpm.conf配置文件做具体配置。如pm.max_children指定的是最大的进程数量,pm.max_requests指定的是每个进程处理完多少个请求后重启(避免内存泄漏)。

php-fpm的多进程模式可以分为静态模式和动态模式。静态模式是指直接开启指定数量的php-fpm进程,不再增加或者减少。动态模式是指开始时启动一定数量的php-fpm进程,然后根据实际情况的变化动态地增加进程或者释放进程。

php-fpm作为php的多进程管理器,当用Nginx作为Web Server时,来自用户的请求会根据Nginx的路由配置把以php为后缀名的文件转发给php-fpm。

Swoole

Swoole是一个高性能的网络框架,使用事件驱动的、异步的、非阻塞的I/O(输入/输出)模型。它可用于开发高性能、可拓展、并发TCP、UDP、Unix套接字、HTTP、Websocket服务。

Swoole在Windows平台上不可用。

Swoole专为构建大规模并发系统而设计,它是用C/C++编写的,并作为PHP的拓展安装。

多线程

基本概念

线程

  1. 线程(thread)是进程的实际运作单位,是CPU调度和分配的基本单位。
  2. 一个线程是指进程中一个单一顺序的控制流程。
  3. 一个进程中可以并发多个线程,每个线程可执行不同的任务。
  4. 同一个进程内的线程可以共享内存变量,实现进程内通信。线程读写变量时存在同步问题,需要加锁。
  5. 线程比进程更加轻量级,对系统资源的消耗更少。
  6. 某个线程运行出现严重错误,会导致整个进程崩溃。

多线程

  1. 多线程的创建和切换的系统开销一般比多进程要小,所以一定程序上会比多进程更高效。
  2. 一个多线程程序比单线程程序被操作系统调度的概率更大,所以多线程程序一般比单线程程序更高效。
  3. 多线程程序的多个线程可以在多个cpu的多个核心同时进行,可以充分发挥机器多核的优势。
  4. 多线程方案也是可以优化的,乱用多线程不一定就能使程序运行得更高效,因为线程的创建和销毁、上下文切换、线程同步等也是有性能损耗的,耗费时间可能比顺序执行的代码还多。
  5. PHP为多线程的应用模型提供了一个安全机制-Zend(禅)线程安全(Zend Thread Safe,ZTS)。
  6. 是否使用多线程还要根据具体情况来定,一般考虑以下两种情况:
  1. .代码中I/O多(I/O阻塞会使操作系统发生任务调度,阻塞当前任务)的情况下,可考虑使用多线程时将代码并行。例如多次读整块的文件,或请求多个网络资源。
  2. .多线程能充分利用CPU,所以有多处大计算量代码时,可以使用多线程让它们并行执行。

PHP实现多线程

PHP默认不支持多线程,如果需要用到多线程,则需要安装pthread拓展(PHP版本>5.3)。而安装pthread拓展,必须用--enable-maintainer-zts参数重新编译PHP,这个参数是指定编译PHP时使用线程安全方式。

PHP实现的线程安全主要是通过TSRM机制(可理解为是:线程安全运行机制)对全局变量和静态变量进行了隔离,将全局变量和静态变量给每个线程复制了一份,各线程使用的全局变量和静态变量都是主线程使用的全局变量和静态变量的一个备份,从而避免了变量冲突,也就避免了出现线程安全问题。

PHP对多线程的封装保证了线程安全,程序员不需要因使用多线程考虑给全局变量加各种锁以避免读写冲突,同时减少了出错的机会,写出来的代码更加安全,这保持了PHP简单易用的一贯风格。但由此导致了子线程一旦开始运行,主线程便无法对子线程运行细节进行调整,线程一定程度上失去了线程之间通过全局变量进行消息传递的能力。

PHP开启线程安全选项后,使用TSRM机制分配和使用变量时会有额外的损耗,因此在不需要使用多线程的PHP环境中,可以考虑使用PHP的NTS(非线程安全)版本。

虽然每个PHP脚本的执行是单线程的,但是Web服务器组件如Apache可采用多线程模型,可以通过Web服务器本身的多线程来处理客户端请求,实现多线程处理的效果。

异步处理

PHP的执行默认是阻塞式的,当需要执行很耗时的操作,而其结果又不需要返回给客户端时,就可以考虑采用异步处理的方式完成。

可实现异步处理的方式:

1. 推荐使用fsockopen函数,此函数的功能为初始化一个套接字连接到指定主机。默认情况下将以阻塞模式开启套接字连接,可以通过stream_set_blocking()将其切换为非阻塞方式开启套接字连接。注意在此函数实际执行中,客户端连接断开或者连接超时都可能导致执行不完整,因此需要加上:

ignore_user_abort(true); //忽略客户端断开。

set_time_limit(0); //取消脚本最大执行时间限制。

2. 使用curl。设置curl的超时时间CURLOPT_TIMEOUT为1,因此客户端需要等1秒钟。

分布式系统

分布式网络存储技术是将数据分散地存储在多台服务器上。分布式网络存储系统采用可拓展的系统结构,利用多台服务器分担存储负荷,使用位置服务器定位存储信息。

php网站采用的分布式系统架构组成成分可能有:

  1. .Nginx反向代理。
  2. .静态资源服务器/CDN(内容分发网络)。
  3. .Web集群(运行相同的Web应用)。
  4. .NAS(网络附属存储)文件服务器/OSS(对象存储)。
  5. .Redis服务器(Web集群内共享Session)。
  6. .队列系统等(其它语言的后端支持)。
  7. .分布式Mysql(主数据库、从数据库、备用主数据库)。

对PHP并发、多进程、多线程、异步处理、分布式系统的一些了解相关推荐

  1. Python高并发爬虫测评(2): 多进程, 多线程和异步协程哪个快?

    在Python爬虫下一代网络请求库httpx和parsel解析库测评一文中我们对比了requests的同步爬虫和httpx的异步协程爬虫爬取链家二手房信息所花的时间(如下所示:一共580条记录),结果 ...

  2. 【进阶】 --- 多线程、多进程、异步IO实用例子

    [进阶] --- 多线程.多进程.异步IO实用例子:https://blog.csdn.net/lu8000/article/details/82315576 python之爬虫_并发(串行.多线程. ...

  3. io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程

    图/文:迷神 我们在Python爬虫中,重要的是讲究速度,如果有10万或者100万Url地址,写过爬虫的都会知道,那估计是非常慢的.我们的Python爬虫一般IO密集型业务,Python爬虫程序需要发 ...

  4. 一则故事表达:并发,并行,同步,异步,线程,多线程

    一个小事件说明下并发,并行,同步,异步,线程,多线程 一个广交会举办向8间公司发起展览邀请, 参展公司有8间,场地有80万平方米的展示区域, 每个参展商有10万平方米可以用于展出售卖, 每个参展公司仅 ...

  5. 并发编程含义比较广泛,包含多线程编程、多进程编程及分布式程序等 目录 1. “共享内存系统”,消息传递系统”。 1 1.1. 共享模式 多进程 多线程 1 1.2. Actor消息模式 事件驱动 2

    并发编程含义比较广泛,包含多线程编程.多进程编程及分布式程序等 目录 1. "共享内存系统",消息传递系统". 1 1.1. 共享模式 多进程 多线程 1 1.2. Ac ...

  6. Python多线程多进程、异步、异常处理等高级用法

    文章目录 前言 多线程多进程 多线程 多进程 协程 总结 异步 基本概念 异步编程 asyncio aiohttp 异常 常见异常 异常处理 自定义异常 lambda表达式 lambda表达式用法 高 ...

  7. python 多进程并发与多线程并发总结

    本文对python支持的几种并发方式进行简单的总结. Python支持的并发分为多线程并发与多进程并发(异步IO本文不涉及).概念上来说,多进程并发即运行多个独立的程序,优势在于并发处理的任务都由操作 ...

  8. 多CPU 多核CPU | 多进程 多线程 | 并行 并发

    文章目录 区分 多CPU && 多核CPU CPU缓存 并行 && 并发 多CPU && 多核CPU | 多进程 && 多线程 | 并行 ...

  9. Python|并发编程|爬虫|单线程|多线程|异步I/O|360图片|Selenium及JavaScript|Scrapy框架|BOM 和 DOM 操作简介|语言基础50课:学习(12)

    文章目录 系列目录 原项目地址 第37课:并发编程在爬虫中的应用 单线程版本 多线程版本 异步I/O版本 总结 第38课:抓取网页动态内容 Selenium 介绍 使用Selenium 加载页面 查找 ...

  10. 哎呀,你对高并发与多线程的解决思路了解的还挺深!

    一.大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战.如果Web系统不做针对性的优化,会轻而易举地陷入到异常状态.我们现在 ...

最新文章

  1. sqlyog连接服务出现的2003和1130错误问题
  2. 安装face_recognition
  3. Ribbon-负载均衡原理
  4. Java EE之旅02 CSS基础
  5. 医院计算机管理工资,医院工资管理系统的设计与开发
  6. 转进制(信息学奥赛一本通-T1161)
  7. php 生成随机数组,利用php如何获取随机数组列表
  8. python新手入门代码-新手零基础入门Python项目实战
  9. java 反射 静态成员_java 利用反射获取内部类静态成员变量的值
  10. 浙江大学公共管理学院与阿里云计算有限公司达成战略合作 | 凌云时刻
  11. MIMO系统获取复用增益
  12. 驰为HI8刷Win10系统出现红屏错误如何解决
  13. minmax()函数
  14. Linux文件夹作用
  15. NFS挂载失败: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.
  16. 大数据测试是什么意思?测试分析方法有哪些?
  17. GNU开发工具的使用方法
  18. diskgenius创建efi分区_复制文件到当前分区
  19. Linux-ARM开发
  20. 设计自己的地图叠加到 Google Maps或者 MicroSoft Vitual Earth

热门文章

  1. 在线文字转语音哪个比较好
  2. python生成器单线程_「Python异步编程-3」协程、生成器、yield 的联系
  3. 科学知识图谱绘制方法、步骤及工具
  4. 深信服AC_禁止访问微信公众号
  5. JavaSE学习笔记-Day1
  6. gradle第三方Jar包依赖统一管理
  7. PTC Creo 4.0 M150
  8. 也谈逆商AQ--献给我的朋友梁斌
  9. 量化投资学习-5:股票与美女5-美女的容貌:K线图
  10. 益和VA市场发展良好,产品稳定两增一减