保藏本站 保藏本站
188bet注册网主页 - 软件测验 - 常用手册 - 站长东西 - 技能社区
主页 > JavaScript > nodejs > 正文

主页 - PHP - 数据库 - 操作体系 - 游戏开发 - JS - Android - MySql - Redis - MongoDB - Win8 - Shell编程 - DOS指令 - jQuery - CSS款式 - Python - Perl

Access - Oracle - DB2 - SQLServer - MsSql2008 - MsSql2005 - Sqlite - PostgreSQL - node.js - extjs - JavaScript vbs - Powershell - Ruby

node 运用进程通讯完成Cluster同享内存

Node.js的标准API没有供给进程同享内存,可是经过IPC接口的send办法和对message事情的监听,就能够完成一个多进程之间的协同机制,经过通讯来操作同享内存。

##IPC的根本用法:

// worker进程 发送音讯
process.send(‘读取同享内存');
 
// master进程 接纳音讯 -> 处理 -> 发送回信
cluster.on('online', function (worker) {
   // 有worker进程树立,即开端监听message事情
   worker.on(‘message', function(data) {
     // 处理来自worker的恳求
     // 回传成果
     worker.send(‘result')
   });
});

在Node.js中,经过send和on(‘message', callback)完成的IPC通讯有几个特色。首要,master和worker之间能够相互通讯,而各个worker之间不能直接通讯,可是worker之间能够经过master转发完成直接通讯。别的,经过send办法传递的数据,会先被JSON.stringify处理后再传递,接纳后会再用JSON.parse解析。所以Buffer目标传递后会变成数组,而function则无法直接传递。反过来说,便是能够直接传递除了buffer和function之外的一切数据类型(现已很强壮了,而且buffer和function也能够用变通的办法完成传递)。

依据以上特色,咱们能够规划一个经过IPC来同享内存的计划:

1、worker进程作为同享内存的运用者,并不直接操作同享内存,而是经过send办法告诉master进程进行写入(set)或许读取(get)操作。

2、master进程初始化一个Object目标作为同享内存,并依据worker发来的message,对Object的键值进行读写。

3、由于要运用跨进程通讯,所以worker建议的set和get都是异步操作,master依据恳求进行实践读写操作,然后将成果回来给worker(即把成果数据send给worker)。

##数据格局

为了完成进程间异步的读写功用,需求对通讯数据的格局做一点标准。

首要是worker的恳求数据:

requestMessage = {
  isSharedMemoryMessage: true, // 表明这是一次同享内存的操作通讯
  method: ‘set', // or ‘get' 操作的办法
  id: cluster.worker.id, // 建议操作的进程(在一些特别场景下,用于确保master能够回信)
  uuid: uuid, // 此次操作的(用于注册/调用回调函数)
  key: key, // 要操作的键
  value: value // 键对应的值(写入)
}

master在接到数据后,会依据method履行相应操作,然后依据requestMessage.id将成果数据发给对应的worker,数据格局如下:

responseMessage = {
  isSharedMemoryMessage: true, // 符号这是一次同享内存通讯
  uuid: requestMessage.uuid, // 此次操作的仅有标明
  value: value // 回来值。get操作为key对应的值,set操作为成功或失利
}

标准数据格局的含义在于,master在接纳到恳求后,能够将处理成果发送给对应的worker,而worker在接到回传的成果后,能够调用此次通讯对应的callback,然后完成协同。

标准数据格局后,接下来要做的便是规划两套代码,别离用于master进程和worker进程,监听通讯并处理通讯数据,完成同享内存的功用。

##User类

User类的实例在worker进程中作业,担任发送操作同享内存的恳求,并监听master的回信。

var User = function() {
  var self = this;
  self.__uuid__ = 0;
 
  // 缓存回调函数
  self.__getCallbacks__ = {};
 
  // 接纳每次操作恳求的回信
  process.on('message', function(data) {
    
    if (!data.isSharedMemoryMessage) return;
    // 经过uuid找到相应的回调函数
    var cb = self.__getCallbacks__[data.uuid];
    if (cb && typeof cb == 'function') {
      cb(data.value)
    }
    // 卸载回调函数
    self.__getCallbacks__[data.uuid] = undefined;
  });
};
 
// 处理操作
User.prototype.handle = function(method, key, value, callback) {
 
  var self = this;
  var uuid = self.__uuid__++;
 
  process.send({
    isSharedMemoryMessage: true,
    method: method,
    id: cluster.worker.id,
    uuid: uuid,
    key: key,
    value: value
  });
 
  // 注册回调函数
  self.__getCallbacks__[uuid] = callback;
 
};
 
User.prototype.set = function(key, value, callback) {
  this.handle('set', key, value, callback);
};
 
User.prototype.get = function(key, callback) {
  this.handle('get', key, null, callback);
};

##Manager类

Manager类的实例在master进程中作业,用于初始化一个Object作为同享内存,并依据User实例的恳求,在同享内存中添加键值对,或许读取键值,然后将成果发送回去。

var Manager = function() {
 
  var self = this;
  
  // 初始化同享内存
  self.__sharedMemory__ = {};
    
  // 监听并处理来自worker的恳求
  cluster.on('online', function(worker) {
    worker.on('message', function(data) {
      // isSharedMemoryMessage是操作同享内存的通讯符号
      if (!data.isSharedMemoryMessage) return;
      self.handle(data);
    });
  });
};
 
Manager.prototype.handle = function(data) {
  var self = this;
  var value = this[data.method](data);
 
  var msg = {
    // 符号这是一次同享内存通讯
    isSharedMemoryMessage: true,       
    // 此次操作的仅有标明
    uuid: data.uuid,
    // 回来值
    value: value
  };
 
  cluster.workers[data.id].send(msg);
};
 
// set操作回来ok表明成功
Manager.prototype.set = function(data) {
  this.__sharedMemory__[data.key] = data.value;
  return 'OK';
};
 
// get操作回来key对应的值
Manager.prototype.get = function(data) {
  return this.__sharedMemory__[data.key];
};

##运用办法

if (cluster.isMaster) {
 
  // 初始化Manager的实例
  var sharedMemoryManager = new Manager();
 
  // fork第一个worker
  cluster.fork();
 
  // 1秒后fork第二个worker
  setTimeout(function() {
    cluster.fork();
  }, 1000);
   
} else {
 
  // 初始化User类的实例
  var sharedMemoryUser = new User();
 
  if (cluster.worker.id == 1) {
    // 第一个worker向同享内存写入一组数据,用a符号
    sharedMemoryUser.set('a', [0, 1, 2, 3]);
  }
 
  if (cluster.worker.id == 2) {
    // 第二个worker从同享内存读取a的值
    sharedMemoryUser.get('a', function(data) {
      console.log(data); // => [0, 1, 2, 3]
    });
  }
  
}

以上便是一个经过IPC通讯完成的多进程同享内存功用,需求留意的是,这种办法是直接在master进程的内存里缓存数据,有必要留意内存的运用情况,这儿能够考虑参加一些简略的筛选战略,优化内存的运用。别的,假如单次读写的数据比较大,IPC通讯的耗时也会相应添加。

完好代码:https://github.com/x6doooo/sharedmemory

以上便是本文的全部内容,期望对我们的学习有所协助,也期望我们多多支撑188bet注册网。

Express系列之multer上传的运用
这两天在看《nodejs威望攻略》,这本书看了好久了,可是读的一向不细,这次才好好看了一遍。收成仍是蛮多的,首要在于wenpack运用的一些细节问题,

Mac 装置 nodejs办法(图文具体过程)
这几日由于需求需求又暂时用到nodejs,之前装置过好几回,可是每次仍是不由得百度下,所以这次在此mark下Mac下nodejs的装置和查验,给自己留个符号,

Node.js学习教程之HTTP/2服务器推送【译】
前语最近Node.jsv8.4+版别发布带来了体验版的HTTP/2,你能够自己经过设置参数--expose-http2发动。这篇文章,我将介绍HTTP/2最重要的一方面服务器推送而且创

本周排行

更新排行

强悍的草根IT技能社区,这儿应该有您想要的! 友情链接:b2b电子商务
Copyright © 2010 touzhuwang75.com. All Rights Rreserved  京ICP备05050695号