php多进程ipc
由于php没有多线程机制,在一些cpu密集型任务时,只能起多进程操作,于是要考虑进程间通信等场景。
php已有方式包括:管道、消息队列、共享内存、socket,如下重点探究文件与共享内存
const SHM_VAR = 1;
const M = 20000;
const N = 100000;
const NUM = 10;
/**
* 文件
*/
function pipe()
{
// 申请锁资源
$sem_key = ftok( __FILE__, 'b' );
$sem_id = sem_get( $sem_key );
// 创建文件
$pipePath = "pipe1";
$file = fopen( $pipePath, 'w+');
fwrite( $file, 0);
for( $i = 0; $i < NUM; $i++ ){
$pid = pcntl_fork();
if( $pid < 0 ){
exit(-1);
}
if( $pid ==0 ) {
for ($j = M+$i; $j<=N; $j+=NUM) {
$mark =1;
for($n=2; $n
if ($j % $n == 0) {
$mark = 0;
break;
}
}
if ($mark) {
sem_acquire($sem_id );
$file = fopen( $pipePath, 'r+');
$count= (int)fread( $file, 5);
$count++;
$file = fopen( $pipePath, 'w+');
fwrite($file, $count);
sem_release( $sem_id );
}
}
exit(-1);
}
}
for($n=0;$n
{
pcntl_wait($status);
}
$file = fopen( $pipePath, 'r+');
echo (int)fread($file, 5) . PHP_EOL;
}
/**
* 共享内存
*/
function shareMemory()
{
// 申请锁资源
$sem_key = ftok( __FILE__, 'b' );
$sem_id = sem_get( $sem_key );
// 申请共享内存
$shm_key = ftok( __FILE__, 'm' );
$shm_id = shm_attach( $shm_key, 1024, 0666 );
//共享内存初始化
shm_put_var( $shm_id, SHM_VAR, 0 );
for( $i = 0; $i < NUM; $i++ ){
$pid = pcntl_fork();
if( $pid < 0 ){
exit(-1);
}
if( $pid ==0 ) {
for ($j = M+$i; $j<=N; $j+=NUM) {
$mark =1;
for($n=2; $n
if ($j % $n == 0) {
$mark = 0;
break;
}
}
if ($mark) {
// 获取锁
sem_acquire($sem_id );
if( shm_has_var( $shm_id, SHM_VAR ) ){
$counter = shm_get_var( $shm_id, SHM_VAR );
$counter += 1;
shm_put_var( $shm_id, SHM_VAR, $counter );
}
sem_release( $sem_id );
}
}exit(-1);
}
}
for($n=0;$n
{
pcntl_wait($status);
}
echo '最终结果'.shm_get_var( $shm_id, SHM_VAR ).PHP_EOL;
// 记得删除共享内存数据,删除共享内存是有顺序的,先remove后detach,顺序反过来php可能会报错
shm_remove( $shm_id );
shm_detach( $shm_id );
}
文件需要上锁保证进程同步性,同时会存在大量系统调用,读文件、写文件速度不如共享内存快;
共享内存,外加锁机制可是实现多个进程对同一块内存进行操作。