PHP进程间通信--信号量与共享内存

PHP提供了两种实现共享内存的扩展。下面我们来一一讲解。

一、shmop 系类函数

注意两点:
1、shmop_read 函数 第2个参数 是读取的起始位置,第3个参数是要读取的长度,如果你要读取的长度小于信息长度,原信息会被截断成你指定的长度。
2、shmop_write 函数 仅可写 字符串 内容!

二、用 Semaphore 扩展中的 sem 类函数 (用起来更方便,类似 key-value 格式)

shm_put_var 第三个参数 写入的值 是一个混合类型,所以没有shmop_write的局限性。
注意:$shar_key 只能是 int 型的参数。

介绍完了php如何创建、操作共享内存,下面我们来看一下,他们如何在进程间通信发挥作用吧。

 0 ){
        unset( $childList[$childPid] );
    }
}

//父进程读取共享内存中的值
$count = shm_get_var($shm_id, SHARE_KEY);
echo "final count is " . $count . PHP_EOL;


//3、去除内存共享区域
#从系统中移除
shm_remove($shm_id);
#关闭和共享内存的连接
shm_detach($shm_id);

逻辑很简单,开启3个进程,对同一个共享内存中的数据进行读写。有一个count的值,如果读到就+1,下面我们看一下运行结果:

PHP进程间通信--信号量与共享内存_第1张图片
image

从结果中我们可以看到,最终的 count 的值还是0。这是为什么呢?简单分析一下,不难发现,当我们开启创建进程的时候,3个子进程同时打开了 共享内存区域,此时他们几乎是同步的,所以读到的信息都是没有count值,此时他们执行自己的业务逻辑然后将 count 为0的结果写入内存区域。这并不是我们想要的结果,三个子进程互相抢占了资源,这是不合理的,那怎么规避这个问题呢?答案是通过 信号量 !

信号量

信号量是什么? 信号量 : 又称为信号灯、旗语 用来解决进程(线程同步的问题),类似于一把锁,访问前获取锁(获取不到则等待),访问后释放锁。

举一个生活中的例子:以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用

下面我们来看一下信号量的几个函数:

注释的很详细了,不懂的还可以查看一下手册的介绍。那么我们现在就用信号量来修改我们的方法吧。

 0 ){
        unset( $childList[$childPid] );
    }
}

//父进程读取共享内存中的值
$count = shm_get_var($shm_id, SHARE_KEY);
echo "final count is " . $count . PHP_EOL;


//3、去除内存共享区域
#从系统中移除
shm_remove($shm_id);
#关闭和共享内存的连接
shm_detach($shm_id);

运行结果:


PHP进程间通信--信号量与共享内存_第2张图片
image.png

完美的处理了进程之间抢资源的问题,实现了操作的原子性!

参考文章:
http://www.cnblogs.com/siqi/p/3999222.html
http://www.cnblogs.com/siqi/p/3997444.html
http://www.jianshu.com/p/08bcf724196b

你可能感兴趣的:(PHP进程间通信--信号量与共享内存)