多进程共享内存的MemoryStream
2024-09-19 04:37:04
文章转载于http://www.raysoftware.cn/?p=506
具体用处呢,有很多,比如多进程浏览器共享Cookie啦,多个进程传送点数据啦.
共享内存封装.
封装成了MemoryStream的形式.
用法如下:
var
ms : TShareMemStream;
ms := TShareMemStream.Create('Global\test', 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.
最新文章
- windows2003 IIS6.0右键属性没有asp.net选项卡的解决办法
- 《Administrator&#39;s Guide》之Managing Memory
- XMAL语法系列之-(2)---WPF控件继承图
- 802.1x协议&;eap类型
- php防注入留言板(simple)
- HDU 1513 Palindrome
- 13.Object-C--浅谈Foundation框架常用的结构体
- JUC全景图
- Java之旅(一)---说说“异常”那些事
- Objective-C马路成魔【12-分类和协议】
- position定位和添加阴影
- xlsx批量转为utf8的csv
- Day5_模块与包(import)(form......import....)
- Springboot整合Kfka
- ORACLE11G R2 RAC的进程启动流程
- hackbar增强版 &; 在Firefox上安装未通过验证的扩展
- tp剩余未验证内容-7
- 浅谈 MVC 和 MTV
- Distributed Systems 分布式系统
- MDI多文档窗体--在一个窗体中装载多个窗体