时隔10年了,我又回来了。说一说进程间共享的问题。

jorry桥

在论坛里看到很多关于多个worker之间如何实现读取同一个数据的问题。如下:
截图

其实这个问题说简单也简单,但多少还是要切换一下思维或应该去了解一下基础知识。
在操作系统中,进程在资源处理层是独立存在的,即多进程之间永远是相互独立的!它们天然是不可能共用一个所谓的变量的。不论是所属主进程还是衍生子进程都是这样。所以不要妄想使用引用的方式将变量地址传递给其它进程!!!
因此,这种隔离性有好也有坏,隔离就相互不干扰避免数据污染,太隔离了又会导致数据不互通不方便,具体就要看场景了。
大家应该经常遇到这个东西:IPC。
即进程间通信(IPC - Interprocess communication),就是在不同进程之间传播或交换信息。
这就是说,进程间共享信息是一门单独的学问,没那么简单的。

拿linux来说,IPC相关的内容就是解决进程间数据共享的,它们之间的共享方式,重点就两个字:通信。
是的,是通信,有通信就必然是有网络的有协议的,所以说,这也并非是一个好处理的东西。

然后推荐看看GlobalData数据共享组件的两个文件:Server和Client,简单的过一下就理解了。
本来就是服务端监听一个本地端口,然后在任意进程中的客户端连接这个端口访问数据,基于这种通信的逻辑实现数据共享。

希望我的理解能快速打通您对多进程编程的认知。

309 4 4
4个评论

jorry桥

看看这个例子就明白了:

<?php

use Workerman\Worker;
use Workerman\Timer;

require_once __DIR__ . '/vendor/autoload.php';

$time = date('Ymd-H:i:s');
Worker::$stdoutFile = __DIR__ . "/logs/process-$time.log";

// 进程间通信
new \GlobalData\Server('0.0.0.0', 8089);

// 同进程变量操作测试
$samevar = 0;

$taskWorker = new Worker();
$taskWorker->name = 'testWorker';
$taskWorker->count = 2;
$taskWorker->user = 'www';
$taskWorker->onWorkerStart = function ($worker) use (&$samevar) {
    $global = new \GlobalData\Client('0.0.0.0:8089'); // 当前子进程共享全局资源
    $global->add('g_add', 0); // 初始化为0

    Timer::add(2, function () use ($worker, &$samevar, $global) {
//        global $global;
        $global->increment('g_add', 1);

        echo '进程PID:'.posix_getpid().' 执行次数:'.++$samevar."\n";
        echo '所有子进程执行总次数:'.$global->g_add."\n";
    });
};

// 运行worker
Worker::runAll();

  • 暂无评论
Tinywan

不错

  • 暂无评论
chaz6chez

https://www.workerman.net/plugin/133

这个基于apcu也就是mmap的共享内存进行IPC,不涉及到通讯,不涉及到网络堆栈,性能更高

  • jorry桥 12天前

    不错不错,我说的多少有点绝对了 ^_^

掌柜

workerman原来已经十年了

  • 暂无评论

jorry桥

2314
积分
0
获赞数
0
粉丝数
2014-08-17 加入
×
🔝