php 进/线/协程


进程是并发执行程序在执行中,分配和管理资源的基本单位,
线程是进程的一个执行单元,比进程 要小的独立运行的基本单位,
一个程序至少有一个进程 一个进程至少有一个线程
php 多进程
在开发业务逻辑层面 并行处理多个任务的一种开发方式,
如给10万 会员发送邮件 每个邮件需要处理1秒 一个进程处理 得10万 1秒才能处理完
开启多个进程同时处理 如 10个进程 那只需要10万/10 秒就能处理完成 缩短了10倍的时间
多进程的概念
多进程主要 在开发 业务逻辑 层面 并行处理多个任务的开发方式,
php-fpm 是 fast-cgi 进程管理器 启动之后会启动 多个fast-cgi进程 等待任务处理,
php-fpm软件层面 fast-cgi的多个进程就属于多进程处理,
用户发起请求
由nginx交给php-fpm处理请求时,
在这个层面 每个请求其实只占有一个 php fast-cgi 进程 进行处理逻辑,
对于 运行业务逻辑 的 这个php进程其实是单进程的,
同理 当直接运行一个php文件时 默认是只开启了一个php进程进行运行php的代码
多进程的开发场景
在传统web模式下 php 是单进程处理业务逻辑 只有在php-cli模式下,用于处理异步任务 作为网络服务器时 才可能用到 多进程处理
伪多进程
传统web 一个请求就是一个进程 可以通过这个方法 实现理论上的多进程
在一个php文件中 写消费任务逻辑 比如给队列中的会员id发送邮件(注意超时 注意用户端关闭不终止脚本)
用网页访问这个php文件 相当于开启了一个进程处理,再开第二个网页访问这个文件 相当于又开启了一个进程
如此重复 可以得到n个处理邮件的进程,针对于 消费 任务逻辑层面 已经是开启了多进程在处理了
多进程使用
在一个php脚本中 开启多进程处理,使用2种方法 linux php-cli环境
pcntl 扩展
pcntl 是php官方的多进程扩展 只能在linux环境使用
$num=1;
$str="Hello world \n";
$pid = pcntl_fork();//新开一个子进程 上面的变量 内存将会 复制一份到子进程中 这个函数,
在主进程中 返回子进程进程id 在子进程返回0 开启失败在主进程返回-1
echo $str;
// 下面的代码 将会被主进程 子进程共同执行
if($pid>0){//主进程代码
    echo "我是主进程,子进程的pid是{$pid}\n";
}elseif($pid==0){
    echo "我是子进程,我的pid是".getmypid()."\n";
}else{
    echo "我是主进程,我现在慌得一批,开启子进程失败了\n";
}
swoole扩展面向生产环境的 PHP 异步网络通信引擎 也有 进程管理模块
$num = 1;
$str = "Easy Swoole\n";
$process = new swoole_process(function () use ($str) {//实例化一个进程类,传入回调函数
    echo $str;//变量内存照常复制一份 不过swoole的开启子进程后使用的是回调方法运行
    echo "我是子进程 我的pid是" . getmypid() . "\n";
});
$pid = $process->start();//开启子进程,创建成功返回子进程的PID,创建失败返回false。
echo $str;
if ($pid > 0) {//主进程代码
    echo "我是主进程 子进程的pid是{$pid}\n";
}else{
    echo "我是主进程 现在不慌了 失败就失败吧\n";
}
进程通信
各进程 内存空间 不一致 各个变量 在不同的内存空间
用户A访问服务端 $_SESSION['user']=1;
用户B同时访问服务端 读取 $_SESSION['user'] 是读取不到的 进程之间内存不是相同的
在php多进程中 pcntl_fork 之后 虽然能读取到之前的变量 但这个变量是复制出来的一份 和原来 存储位置 不同
$str = "Swoole\n";
$pid = pcntl_fork();
if($pid>0){
    $str="Tioncico\n";//在主进程修改了$str,不会影响到子进程的$str变量
    echo $str;
}elseif ($pid==0){
    echo $str;//$str是pcntl_fork复制出来的
}else{
}
多进程中 无法直接通信  可以使用以下几种方式进行通信
管道通信 分为 有名管道 无名管道等
消息队列通信
使用linux消息队列 通过sysvmsg扩展 //www.php20.cn/article/137
进程信号通信
共享内存通信
映射 能被其他进程所访问的内存 这段共享内存由 进程创建 但多个进程都可以访问
共享内存是最快的 IPC 方式 是针对其他进程间通信方式运行效率低而专门设计的  与其他通信机制 如 信号量 配合使用 实现 进程间 同步和通信
套接字通信
第三方通信 使用文件操作 mysql redis 等 实现通信