python 基於mmap模塊的jsonmmap實現本地多進程內存共享

python 基於mmap模塊的jsonmmap實現本地多進程內存共享

###1.概述python

  • 共享內存能夠說是最有用的進程間通訊方式.兩個不用的進程共享內存的意思是:同一塊物理內存被映射到兩個進程的各自的進程地址空間.一個進程能夠及時看到另外一個進程對共享內存的更新,反之亦然.採用共享內存通訊的一個顯而易見的好處效率高,由於進程能夠直接讀寫內存,而不須要任何數據的複製.對於向管道和消息隊列等通訊等方式,則須要在內核和用戶空間進行四次的數據複製,而共享內存則只須要兩次數據複製:一次從輸入文件到共享內存區,另外一個從共享內存區到輸出文件.實際上,進程之間在共享內存時,並不老是讀寫少許數據後就解除映射,有新的通訊時,再從新創建共享內存區域.而是保持共享區域,知道通訊完畢爲止,這樣,數據內容就一直保存在共享內存中,並無寫回文件.共享內存中的內容每每是在解除映射時才寫回文件的.所以,採用共享內存的通訊方式效率很是高.linux

  • mmap系統調用是的是的進程間經過映射同一個普通文件實現共享內存.普通文件被映射到進程地址空間後,進程能夠向像訪問普通內存同樣對文件進行訪問,沒必要再調用read,write等操做.與mmap系統調用配合使用的系統調用還有munmap,msync等. 實際上,mmap系統調用並非徹底爲了用於共享內存而設計的.它自己提供了不一樣於通常對普通文件的訪問方式,是進程能夠像讀寫內存同樣對普通文件操做.而Posix或System V的共享內存則是純粹用於共享內存的,固然mmap實現共享內存也是主要應用之一.git

###2. python mmap模塊詳解github

  • 在python中,mmap.mmap()的函數實如今windows和linux上是不同的,但實現api接口函數很類似,下面以mmap的windows實現爲例說明:json

  • mmap.mmap(fileno, length[, tagname[, access[, offset]]])windows

    • fileno:the file handle fileno, 文件描述符
    • length:共享內存的大小
    • tagname: 共享內存區域的名字,能夠理解爲id
    • access:
      • ACCESS_READ: 只能讀,若是執行寫操做,raises a TypeError exception
      • ACCESS_WRITE: 可讀可寫
      • ACCESS_COPY: 可讀可寫,但不更新到文件中去
  • 函數列表api

    • mmap.close() 斷開映射關係
    • mmap.find(string[, start[, end]]):返回第一個string的索引,不然返回-1
    • mmap.move(dest, src, count): 移動count大小的內容從src到dest
    • mmap.read(num): 根據文件指針的位置兌取num個字節的內容,更新文件指針的位置
    • mmap.read_byte():讀取當前字符,更新文件指針位置
    • mmap.readline():Returns a single line, starting at the current file position and up to the next newline.從當前位置到下一行位置的全部內容
    • mmap.resize(newsize):Resizes the map and the underlying file,改變映射內存與文件大小
    • mmap.rfind(string[, start[, end]]): 返回最後一個string的索引
    • mmap.seek(pos[, whence]): 設置文件指針的位置
    • mmap.size(): 返回共享內存的大小
    • mmap.tell():返回當前指針的位置
    • mmap.write(string):從當前指針位置開始寫入string
    • mmap.write_byte(byte): Write the single-character string byte into memory at the current position of the file pointer; the file position is advanced by 1.

###3.基於mmap和json實現內存共享dom

  • ObjectMmap繼承自mmap,結合json實現python obj的共享函數

    • jsonwrite(obj): 將可json序列化的obj對象寫入共享內存
    • jsonread_master():主進程獲取內存內容
    • jsonread_follower(): 從進程獲取內存內容
  • 自定義的jsonmmap模塊:設計

    #!/usr/bin/python
      # -*- coding: utf-8 -*-
      import mmap
      import json
    
    
      class ObjectMmap(mmap.mmap):
    
          def __init__(self, fileno=-1, length=1024, access=mmap.ACCESS_WRITE, tagname='share_mmap'):
              super(ObjectMmap, self).__init__(self, fileno, length, access=access, tagname=tagname)
              self.length = length
              self.access = access
              self.tagname = tagname
    
          def jsonwrite(self, obj):
              try:
                  self.obj = obj
                  self.seek(0)
                  obj_str = json.dumps(obj)
                  obj_len = len(obj_str)
                  content = str(obj_len) + ":" + obj_str
                  self.write(content)
                  self.contentbegin = len(str(obj_len)) + 1
                  self.contentend = self.tell()
                  self.contentlength = self.contentend - self.contentbegin
                  return True
              except Exception, e:
                  return False
    
          def jsonread_master(self):
              try:
                  self.seek(self.contentbegin)
                  content = self.read(self.contentlength)
                  obj = json.loads(content)
                  self.obj = obj
                  return obj
              except Exception, e:
                  if self.obj:
                      return self.obj
                  else:
                      return None
    
          def jsonread_follower(self):
              try:
                  self.seek(0)
                  index = self.find(":")
                  if index != -1:
                      head = self.read(index + 1)
                      contentlength = int(head[:-1])
                      content = self.read(contentlength)
                      obj = json.loads(content)
                      self.obj = obj
                      return obj
                  else:
                      return None
              except Exception, e:
                  if self.obj:
                      return self.obj
                  else:
                      return None

4.舉例

  • 主進程

    #!/usr/bin/python
      # -*- coding: utf-8 -*-
      import mmap
      from jsonmmap import ObjectMmap
      import random
    
    
      def main():
          mm = ObjectMmap(-1, 1024*1024, access=mmap.ACCESS_WRITE, tagname='share_mmap')
          while True:
              length = random.randint(1, 100)
              p = range(length)
              mm.jsonwrite(p)
              print '*' * 30
              print mm.jsonread_master()
    
      if __name__ == '__main__':
          main()
  • 從進程

    #!/usr/bin/python
      # -*- coding: utf-8 -*-
      import mmap
      from jsonmmap import ObjectMmap
      import time
    
    
      def main():
          mm = ObjectMmap(-1, 1024*1024, access=mmap.ACCESS_READ, tagname='share_mmap')
          while True:
              print '*' * 30
              print mm.jsonread_follower()
    
      if __name__ == '__main__':
          main()

5.應用場景

主進程+多個從進程,主進程負責管理多個從進程,主從進程共享一個可序列化json對象,譬如說共享配置; 主進程才具有權限去修改配置,從進程僅僅具有訪問權限。

詳情請參見dragondjf github

相關文章
相關標籤/搜索