一、概述
关于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 来映射

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