2025年PHP多进程 - Yac扩展的基本原理及其使用教程(cli和fpm)

PHP多进程 - Yac扩展的基本原理及其使用教程(cli和fpm)一 概述 关于 Yac 扩展的介绍 https www laruence com 2020 03 25 5657 html github 地址 https github com laruence yac blob master php 官方文档 https www php net manual zh yac get php Linux 安装 pecl install yac

大家好,我是讯享网,很高兴认识大家。

一、概述

关于Yac扩展的介绍 https://www.laruence.com/2020/03/25/5657.html
github地址 https://github.com/laruence/yac/blob/master
php官方文档 https://www.php.net/manual/zh/yac.get.php

Linux安装 pecl install yac
docker安装 pecl install yac && /usr/local/bin/docker-php-ext-enable yac
记得开启 yac.enable_cli

Yac的设计初衷:PHP进程之间共享一些简单的数据。

阐明三个关键点:
1、PHP进程之间
实现运行中的同族的PHP进程之间,也就是有亲缘关系的进程之间的数据共享,无关的进程不会共享。
同一台机器内部。
类似于 APC,APCu,Swoole-Table。

Yac是鸟哥为php-fpm模式而设计的,可以很方便的实现php-fpm进程之间的数据共享,它同样可以用在cli的master-worker模式下worker与worker之间,worker与master之间的数据共享,比如workerman框架。

二、实践

示例:

demo1.php

<?php $yac = new Yac(); $key = 'name'; $data = $yac->get($key); var_dump($data); while(true){ 
    $yac->set($key, date('Y-m-d H:i:s')); var_dump($yac->get($key)); sleep(1); } 

讯享网

demo2.php


讯享网

讯享网<?php $yac = new Yac(); var_dump($yac->dump(10)); 

使用 curl 先访问 demo1.php, 再访问 demo2.php。可以获取到缓存。

还是上面的两个文件,在cli模式下,先执行 php demo1.php,再开一个窗口执行 php demo2.php,发现读取不到缓存了。这个现象应该是第一次使用yac的同学都会遇到,并且都会一脸懵,其实yac实现PHP进程间数据共享的两个条件是:同族进程,且至少有一个PHP进程在运行中。

1、同族进程
正如上面的php-fpm进程,master和worker都算同族的进程,所以要想在cli下使用yac,那么应该是父子进程的关系,这样father与child,child与child之间才能实现共享。
开启了yac扩展之后,每启动一个PHP进程,yac内部会发起mmap系统调用使得进程之间通过映射匿名文件实现共享内存,虽然是匿名的,但是同族的进程会指向同一个匿名文件,不同族的进程指向不同的匿名文件,从而保护了当前共享内存不受外部不相干的进程的干扰。
所以,上面的例子,两个进程是不同的族,隐射了不同的内存地址,自然不能共享数据。

改进后的 cli 示例

<?php for ($i = 1; $i < 3; $i++) { 
    $pid = pcntl_fork(); $yac = new Yac(); $key = 'name111'; if ($pid > 0) { 
    if ($i == 1) { 
    cli_set_process_title('child_1'); $yac->set($key, date('Y-m-d H:i:s')); file_put_contents('child_1.log', $yac->get($key)); exit; } else { 
    cli_set_process_title('child_2'); sleep(10); // 让子进程1退出,看是否能读到缓存 file_put_contents('child_2.log', $yac->get($key)); exit; } } } // 后台运行了 cli_set_process_title('child_0'); sleep(5); // 确保子进程成功写入缓存 file_put_contents('child_0.log', $yac->get($key)); 

进程 child_0, child_1, child_2 属于同族进程,他们都引用了同一块虚拟内存,就可以共享了。等他们都结束后,该内存就被释放。

三、原理

讯享网checking for sysvipc shared memory support... yes checking for mmap() using MAP_ANON shared memory support... yes checking for mmap() using /dev/zero shared memory support... yes 

依次为:

sysvipc 就是通过物理内存来共享的,使用ipcs -m 可查看共享内存段的使用情况。 mmap 匿名映射模式(不涉及具体的文件名,避免了文件的创建及打开,很显然只能用于具有亲缘关系的进程间通信)。需将 flags 设置为MAP_ANON,fd设置为-1 mmap 指定文件 /dev/zero 来映射,这种是开放的共享,任意进程都可以执行它并实现共享。 

缓存空间初始化。根据当前系统的情况, 选择其中一种方式进行内存的申请、初始化

讯享网mmap -- 匿名映射 shm -- sysvipc filemaping -- 指定文件 /dev/zero 来映射 
小讯
上一篇 2025-03-16 21:31
下一篇 2025-03-16 08:36

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/47910.html