91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

node中怎么利用進程通信實現Cluster共享內存

發布時間:2021-07-21 10:55:15 來源:億速云 閱讀:115 作者:Leah 欄目:web開發

node中怎么利用進程通信實現Cluster共享內存,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

##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]
    });
  }
  
}

關于node中怎么利用進程通信實現Cluster共享內存問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

赤城县| 隆德县| 通江县| 巴青县| 礼泉县| 铁力市| 海晏县| 彭泽县| 清新县| 平罗县| 通道| 平潭县| 西昌市| 米泉市| 台北县| 七台河市| 望奎县| 乌拉特中旗| 定安县| 金平| 彭阳县| 柳州市| 商水县| 太和县| 濮阳市| 石家庄市| 建湖县| 本溪| 离岛区| 绵阳市| 苍山县| 台山市| 白沙| 琼海市| 阳高县| 诸暨市| 商水县| 北川| 高碑店市| 喀什市| 伊金霍洛旗|