• 多进程共享内存的MemoryStream


    文章转载于http://www.raysoftware.cn/?p=506

    具体用处呢,有很多,比如多进程浏览器共享Cookie啦,多个进程传送点数据啦.

    共享内存封装.
    封装成了MemoryStream的形式.
    用法如下:
      var
        ms : TShareMemStream;
      ms := TShareMemStream.Create('Global	est', FILE_MAP_ALL_ACCESS, 4096);
      if (ms.Memory <> nil)(*and(ms.AlreadyExists)*) then
      //如果创建失败Memory指针是空指针
      //AlreadyExists表示已经存在了,也就是之前被别人(也许是别的进程)创建过了.
      begin
        //获取锁,多个进程线程访问安全访问
        if ms.GetLock(INFINITE) then
        begin
          ms.read(...);
          ms.write(...);
          //释放锁
          ms.ReleaseLock();
        end;
      end;
      ms.free;
    

    共享类原文件如下:

    unit ShareMemoryStream;
     
    interface
     
    uses
      SysUtils, Classes, Syncobjs,
      Windows;
     
    type
      TShareMemStream = class(TCustomMemoryStream)
      private
        FFile: THandle;
        FSize: Int64;
        FEvent: TEvent;
        FAlreadyExists: Boolean;
      protected
        property Event: TEvent read FEvent;
      public
        constructor Create(const ShareName: string;
          ACCESS: DWORD = FILE_MAP_ALL_ACCESS; ASize: Int64 = 16 * 1024 * 1024);
        destructor Destroy; override;
     
        function Write(const Buffer; Count: Integer): Longint; override;
     
        function GetLock(ATimeOut: DWORD = INFINITE): Boolean;
        procedure ReleaseLock();
     
        property AlreadyExists: Boolean read FAlreadyExists;
      end;
     
    implementation
     
    procedure InitSecAttr(var sa: TSecurityAttributes; var sd: TSecurityDescriptor);
    begin
      sa.nLength := sizeOf(sa);
      sa.lpSecurityDescriptor := @sd;
      sa.bInheritHandle := false;
      InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
      SetSecurityDescriptorDacl(@sd, true, nil, false);
    end;
     
    { TShareMem }
     
    constructor TShareMemStream.Create(const ShareName: string; ACCESS: DWORD;
      ASize: Int64);
    var
      sa: TSecurityAttributes;
      sd: TSecurityDescriptor;
      lprotect: DWORD;
      e: Integer;
    begin
      FEvent := TEvent.Create(nil, false, true, ShareName +
        '_TShareMemStream_Event');
      FSize := ASize;
      InitSecAttr(sa, sd);
     
      ACCESS := ACCESS and (not SECTION_MAP_EXECUTE);
     
      if (ACCESS and FILE_MAP_WRITE) = FILE_MAP_WRITE then
        lprotect := PAGE_READWRITE
      else if (ACCESS and FILE_MAP_READ) = FILE_MAP_READ then
        lprotect := PAGE_READONLY;
     
      FFile := CreateFileMapping(INVALID_HANDLE_VALUE, @sa, lprotect,
        Int64Rec(FSize).Hi, Int64Rec(FSize).Lo, PChar(ShareName));
      e := GetLastError;
      if FFile = 0 then
        Exit;
      FAlreadyExists := e = ERROR_ALREADY_EXISTS;
      SetPointer(MapViewOfFile(FFile, ACCESS, 0, 0, Int64Rec(FSize).Lo),
        Int64Rec(FSize).Lo);
    end;
     
    destructor TShareMemStream.Destroy;
    begin
      if Memory <> nil then
      begin
        UnmapViewOfFile(Memory);
        SetPointer(nil, 0);
        Position := 0;
      end;
      if FFile <> 0 then
      begin
        CloseHandle(FFile);
        FFile := 0;
      end;
      FEvent.Free;
      inherited Destroy;
    end;
     
    function TShareMemStream.GetLock(ATimeOut: DWORD): Boolean;
    var
      wr : TWaitResult;
    begin
      wr := FEvent.WaitFor(ATimeOut);
      Result := wr = wrSignaled;
    end;
     
    procedure TShareMemStream.ReleaseLock;
    begin
      FEvent.SetEvent;
    end;
     
    function TShareMemStream.Write(const Buffer; Count: Integer): Longint;
    begin
      Result := 0;
      if (Size - Position) >= Count then
      begin
        System.Move(Buffer, PByte(Memory)[Position], Count);
        Position := Position + Count;
        Result := Count;
      end;
    end;
     
    end.
    

      

  • 相关阅读:
    9.8-9.9多校互测与牛客网提高一测
    数位$dp$
    互不侵犯_状压$dp$
    状态压缩dp初学__$Corn Fields$
    树形$dp$学习笔记
    最长公共上升子序列$LCIS$
    区间dp学习笔记
    保护知识产权,让创新更有动力!
    crmeb后台七牛云存储相关配置步骤
    crmeb一款最适合二次开发的开源微信公众号小程序框架
  • 原文地址:https://www.cnblogs.com/sttchengfei/p/10459393.html
Copyright © 2020-2023  润新知