最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

node 利用進(jìn)程通信實(shí)現(xiàn)Cluster共享內(nèi)存

 更新時間:2017年10月27日 11:09:08   作者:x6doooo  
本篇文章主要介紹了node 利用進(jìn)程通信實(shí)現(xiàn)Cluster共享內(nèi)存,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

Node.js的標(biāo)準(zhǔn)API沒有提供進(jìn)程共享內(nèi)存,然而通過IPC接口的send方法和對message事件的監(jiān)聽,就可以實(shí)現(xiàn)一個多進(jìn)程之間的協(xié)同機(jī)制,通過通信來操作共享內(nèi)存。

##IPC的基本用法:

// worker進(jìn)程 發(fā)送消息
process.send(‘讀取共享內(nèi)存');
 
// master進(jìn)程 接收消息 -> 處理 -> 發(fā)送回信
cluster.on('online', function (worker) {
   // 有worker進(jìn)程建立,即開始監(jiān)聽message事件
   worker.on(‘message', function(data) {
     // 處理來自worker的請求
     // 回傳結(jié)果
     worker.send(‘result')
   });
});

在Node.js中,通過send和on(‘message', callback)實(shí)現(xiàn)的IPC通信有幾個特點(diǎn)。首先,master和worker之間可以互相通信,而各個worker之間不能直接通信,但是worker之間可以通過master轉(zhuǎn)發(fā)實(shí)現(xiàn)間接通信。另外,通過send方法傳遞的數(shù)據(jù),會先被JSON.stringify處理后再傳遞,接收后會再用JSON.parse解析。所以Buffer對象傳遞后會變成數(shù)組,而function則無法直接傳遞。反過來說,就是可以直接傳遞除了buffer和function之外的所有數(shù)據(jù)類型(已經(jīng)很強(qiáng)大了,而且buffer和function也可以用變通的方法實(shí)現(xiàn)傳遞)。

基于以上特點(diǎn),我們可以設(shè)計一個通過IPC來共享內(nèi)存的方案:

1、worker進(jìn)程作為共享內(nèi)存的使用者,并不直接操作共享內(nèi)存,而是通過send方法通知master進(jìn)程進(jìn)行寫入(set)或者讀取(get)操作。

2、master進(jìn)程初始化一個Object對象作為共享內(nèi)存,并根據(jù)worker發(fā)來的message,對Object的鍵值進(jìn)行讀寫。

3、由于要使用跨進(jìn)程通信,所以worker發(fā)起的set和get都是異步操作,master根據(jù)請求進(jìn)行實(shí)際讀寫操作,然后將結(jié)果返回給worker(即把結(jié)果數(shù)據(jù)send給worker)。

##數(shù)據(jù)格式

為了實(shí)現(xiàn)進(jìn)程間異步的讀寫功能,需要對通信數(shù)據(jù)的格式做一點(diǎn)規(guī)范。

首先是worker的請求數(shù)據(jù):

requestMessage = {
  isSharedMemoryMessage: true, // 表示這是一次共享內(nèi)存的操作通信
  method: ‘set', // or ‘get' 操作的方法
  id: cluster.worker.id, // 發(fā)起操作的進(jìn)程(在一些特殊場景下,用于保證master可以回信)
  uuid: uuid, // 此次操作的(用于注冊/調(diào)用回調(diào)函數(shù))
  key: key, // 要操作的鍵
  value: value // 鍵對應(yīng)的值(寫入)
}

master在接到數(shù)據(jù)后,會根據(jù)method執(zhí)行相應(yīng)操作,然后根據(jù)requestMessage.id將結(jié)果數(shù)據(jù)發(fā)給對應(yīng)的worker,數(shù)據(jù)格式如下:

responseMessage = {
  isSharedMemoryMessage: true, // 標(biāo)記這是一次共享內(nèi)存通信
  uuid: requestMessage.uuid, // 此次操作的唯一標(biāo)示
  value: value // 返回值。get操作為key對應(yīng)的值,set操作為成功或失敗
}

規(guī)范數(shù)據(jù)格式的意義在于,master在接收到請求后,能夠?qū)⑻幚斫Y(jié)果發(fā)送給對應(yīng)的worker,而worker在接到回傳的結(jié)果后,能夠調(diào)用此次通信對應(yīng)的callback,從而實(shí)現(xiàn)協(xié)同。

規(guī)范數(shù)據(jù)格式后,接下來要做的就是設(shè)計兩套代碼,分別用于master進(jìn)程和worker進(jìn)程,監(jiān)聽通信并處理通信數(shù)據(jù),實(shí)現(xiàn)共享內(nèi)存的功能。

##User類

User類的實(shí)例在worker進(jìn)程中工作,負(fù)責(zé)發(fā)送操作共享內(nèi)存的請求,并監(jiān)聽master的回信。

var User = function() {
  var self = this;
  self.__uuid__ = 0;
 
  // 緩存回調(diào)函數(shù)
  self.__getCallbacks__ = {};
 
  // 接收每次操作請求的回信
  process.on('message', function(data) {
    
    if (!data.isSharedMemoryMessage) return;
    // 通過uuid找到相應(yīng)的回調(diào)函數(shù)
    var cb = self.__getCallbacks__[data.uuid];
    if (cb && typeof cb == 'function') {
      cb(data.value)
    }
    // 卸載回調(diào)函數(shù)
    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
  });
 
  // 注冊回調(diào)函數(shù)
  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類的實(shí)例在master進(jìn)程中工作,用于初始化一個Object作為共享內(nèi)存,并根據(jù)User實(shí)例的請求,在共享內(nèi)存中增加鍵值對,或者讀取鍵值,然后將結(jié)果發(fā)送回去。

var Manager = function() {
 
  var self = this;
  
  // 初始化共享內(nèi)存
  self.__sharedMemory__ = {};
    
  // 監(jiān)聽并處理來自worker的請求
  cluster.on('online', function(worker) {
    worker.on('message', function(data) {
      // isSharedMemoryMessage是操作共享內(nèi)存的通信標(biāo)記
      if (!data.isSharedMemoryMessage) return;
      self.handle(data);
    });
  });
};
 
Manager.prototype.handle = function(data) {
  var self = this;
  var value = this[data.method](data);
 
  var msg = {
    // 標(biāo)記這是一次共享內(nèi)存通信
    isSharedMemoryMessage: true,       
    // 此次操作的唯一標(biāo)示
    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對應(yīng)的值
Manager.prototype.get = function(data) {
  return this.__sharedMemory__[data.key];
};

##使用方法

if (cluster.isMaster) {
 
  // 初始化Manager的實(shí)例
  var sharedMemoryManager = new Manager();
 
  // fork第一個worker
  cluster.fork();
 
  // 1秒后fork第二個worker
  setTimeout(function() {
    cluster.fork();
  }, 1000);
   
} else {
 
  // 初始化User類的實(shí)例
  var sharedMemoryUser = new User();
 
  if (cluster.worker.id == 1) {
    // 第一個worker向共享內(nèi)存寫入一組數(shù)據(jù),用a標(biāo)記
    sharedMemoryUser.set('a', [0, 1, 2, 3]);
  }
 
  if (cluster.worker.id == 2) {
    // 第二個worker從共享內(nèi)存讀取a的值
    sharedMemoryUser.get('a', function(data) {
      console.log(data); // => [0, 1, 2, 3]
    });
  }
  
}

以上就是一個通過IPC通信實(shí)現(xiàn)的多進(jìn)程共享內(nèi)存功能,需要注意的是,這種方法是直接在master進(jìn)程的內(nèi)存里緩存數(shù)據(jù),必須注意內(nèi)存的使用情況,這里可以考慮加入一些簡單的淘汰策略,優(yōu)化內(nèi)存的使用。另外,如果單次讀寫的數(shù)據(jù)比較大,IPC通信的耗時也會相應(yīng)增加。

完整代碼:https://github.com/x6doooo/sharedmemory

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Node.js全局可用變量、函數(shù)和對象示例詳解

    Node.js全局可用變量、函數(shù)和對象示例詳解

    JavaScript中有一個特殊的對象,稱為全局對象(Global Object),它及其所有屬性都可以在程序的任何地方訪問,即全局變量,下面這篇文章主要給大家介紹了關(guān)于Node.js全局可用變量、函數(shù)和對象的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • Nest.js中使用HTTP五種數(shù)據(jù)傳輸方式小結(jié)

    Nest.js中使用HTTP五種數(shù)據(jù)傳輸方式小結(jié)

    本文主要介紹了Nest.js中使用HTTP五種數(shù)據(jù)傳輸方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • node.js中的fs.rename方法使用說明

    node.js中的fs.rename方法使用說明

    這篇文章主要介紹了node.js中的fs.rename方法使用說明,本文介紹了fs.rename的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下的相關(guān)資料
    2014-12-12
  • NodeJS?Express使用ORM模型訪問關(guān)系型數(shù)據(jù)庫流程詳解

    NodeJS?Express使用ORM模型訪問關(guān)系型數(shù)據(jù)庫流程詳解

    這篇文章主要介紹了NodeJS?Express使用ORM模型訪問關(guān)系型數(shù)據(jù)庫流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-01-01
  • 詳解HTTPS 的原理和 NodeJS 的實(shí)現(xiàn)

    詳解HTTPS 的原理和 NodeJS 的實(shí)現(xiàn)

    這篇文章主要介紹了詳解HTTPS 的原理和 NodeJS 的實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • node.js操作mongodb學(xué)習(xí)小結(jié)

    node.js操作mongodb學(xué)習(xí)小結(jié)

    這篇文章主要介紹了node.js操作mongodb學(xué)習(xí)小結(jié),本文給出了mongodb創(chuàng)建數(shù)據(jù)庫、插入數(shù)據(jù)以及連接mongodb數(shù)據(jù)庫并查詢數(shù)據(jù)等代碼實(shí)例,需要的朋友可以參考下
    2015-04-04
  • nodejs微信掃碼支付功能實(shí)現(xiàn)

    nodejs微信掃碼支付功能實(shí)現(xiàn)

    本片文章通過代碼示例給大家詳細(xì)講述了如何用nodejs寫出微信掃碼支付這個功能,有興趣的朋友可以參考下。
    2018-02-02
  • 基于nodejs的雪碧圖制作工具的示例代碼

    基于nodejs的雪碧圖制作工具的示例代碼

    雪碧圖就是把很多小圖標(biāo)合并為一張圖片,這篇文章主要介紹了基于nodejs的雪碧圖制作工具的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Express + Session 實(shí)現(xiàn)登錄驗證功能

    Express + Session 實(shí)現(xiàn)登錄驗證功能

    本文主要介紹在 Express 框架中,如何使用 Session 來實(shí)現(xiàn)用戶登錄身份驗證。對express session實(shí)現(xiàn)登錄驗證相關(guān)知識,感興趣的朋友一起看看吧
    2017-09-09
  • Nodejs調(diào)用WebService的示例代碼

    Nodejs調(diào)用WebService的示例代碼

    本篇文章主要介紹了Nodejs調(diào)用WebService的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09

最新評論

嘉峪关市| 黄浦区| 大同县| 博客| 射洪县| 卢龙县| 巨鹿县| 尉犁县| 松阳县| 灵丘县| 千阳县| 盐池县| 高阳县| 普安县| 黄浦区| 岗巴县| 年辖:市辖区| 突泉县| 西乌珠穆沁旗| 将乐县| 泾源县| 浮梁县| 汶川县| 二手房| 岑溪市| 无锡市| 视频| 仙居县| 长治市| 天长市| 太谷县| 湟中县| 三江| 南丹县| 新余市| 商城县| 抚宁县| 敖汉旗| 东辽县| 柳州市| 泽普县|