Delphi 多进程共享内存的简单封装单元
该单元转自武稀松的博客
稍作修改,使其支持Delphi7
{
共享内存封装.
封装成了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;
MessageBox(0,PChar(IntToStr(e)),0,0);
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, Pointer(Longint(Memory) + Position)^, Count);
Position := Position + Count;
Result := Count;
end;
end;
end.
Delphi 多进程共享内存的简单封装单元的更多相关文章
- c#读写共享内存操作函数封装
原文 c#读写共享内存操作函数封装 c#共享内存操作相对c++共享内存操作来说原理是一样,但是c#会显得有点复杂. 现把昨天封装的读写共享内存封装的函数记录下来,一方面希望给需要这块的有点帮助,另一方 ...
- 多进程共享内存的MemoryStream
文章转载于http://www.raysoftware.cn/?p=506 具体用处呢,有很多,比如多进程浏览器共享Cookie啦,多个进程传送点数据啦. 共享内存封装. 封装成了MemoryStre ...
- Linux进程间通信 共享内存+信号量+简单样例
每个进程都有着自己独立的地址空间,比方程序之前申请了一块内存.当调用fork函数之后.父进程和子进程所使用的是不同的内存. 因此进程间的通信,不像线程间通信那么简单.可是共享内存编程接口能够让一个进程 ...
- (转)OS: 生产者消费者问题(多进程+共享内存+信号量)
转:http://blog.csdn.net/yaozhiyi/article/details/7561759 一. 引子 时隔一年再次用到 cout 的时候,哥潸然泪下,这是一种久别重逢的感动,虽然 ...
- Linux环境编程之共享内存区(一):共享内存区简单介绍
共享内存区是可用IPC形式中最快的.一旦内存区映射到共享它的进程的地址空间,进程间数据的传递就不再涉及内核.然而往该共享内存区存放信息或从中取走信息的进程间通常须要某种形式的同步.不再涉及内核是指:进 ...
- OS: 生产者消费者问题(二) ---- 系统V IPC通信-信号量和共享内存
在上一篇“OS: 生产者消费者问题(多进程+共享内存+信号量)”中提到的方法二: 如果进程之间并没有父子关系,但是协商好了共享存储的 KEY , 那么在每个进程中,就可以通过 KEY 以及 shmge ...
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 VC中进程与进程之间共享内存 .net环境下跨进程、高频率读写数据 使用C#开发Android应用之WebApp 分布式事务之消息补偿解决方案
C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). ...
- DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)
DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...
- php简单使用shmop函数创建共享内存减少服务器负载
在之前的一篇博客[了解一下共享内存的概念及优缺点]已经对共享内存的概念做了说明.下面就来简单使用共享内存(其实也可以用其他工具,比如redis) PHP做内存共享有两套接口.一个是shm,它实际上是变 ...
- C 共享内存封装
引言 - 背景 2016 年写过一篇关于 linux 共享内存 shm api 扫盲文. C扩展 从共享内存shm到memcache外部内存 比较简单. 没有深入分析(能力有限, 也深入分析不了). ...
随机推荐
- chatGPT帮助开发实战解答问题和反思
问题来自.Net开发群友 问题 我想做一个自动生成单据号的功能,但是在EFCORE里没有行级锁,请有什么等价方案吗? ChatGPT回答 在 EF Core 中确实没有提供行级锁(row-level ...
- python之路76 路飞项目 企业项目类型、软件开发流程、路飞项目需求、pip永久换源、虚拟环境、路飞项目前后端创建、包导入、后端项目目录调整
知识获取渠道 cnblogs csdn 掘金 思否 找工作app boss直骗.拉钩.智联.猎聘.脉脉(内推,hr). 企业项目类型 1.面向互联网用户:商城类项目 微信小程序商城 2.面向互联网用户 ...
- 我做的FFmpeg开源C#封装库Sdcb.FFmpeg
我做的FFmpeg开源C#封装库Sdcb.FFmpeg 写在前面: 该主题为2022年12月份.NET Conf China 2022我的主题,项目地址:https://github.com/sdcb ...
- centos7中关闭防火墙命令
1.命令行界面输入命令"systemctl status firewalld.service"并按下回车键. 2.然后在下方可以查看得到"active(running)& ...
- ASP.net EF动态映射实体
1.配置EF与建立实体模型这里不做过多介绍.主要介绍如何动态映射实体模型 1.1.实现过程有很多种方式我们这里使用接口.然后扫描所有继承了该接口的实体类然后映射(也可以自行扩展使用特性) 首先我们新建 ...
- java如何将逗号分隔的字符串转成int或者long数组
String str = "1,2,3";//先将他转化成int的数组如上述:欲将str 转成 数值型数组 利用 split 函数先以 ,分割 String str = " ...
- PO培训
30M 的step by step.带notes 这个文档把常用的包含java都有 不止是配置,反正各种处理都有.. 各种高清无码截图,还不算附件内容
- ACE下载地址
https://download.dre.vanderbilt.edu/previous_versions/ 在某n中找了大半天愣是没人贴出来
- Centos7安装Docker 及 Docker-compose
1.安装环境 此处在Centos7进行安装,可以使用以下命令查看CentOS版本 lsb_release -a 在 CentOS 7安装docker要求系统为64位.系统内核版本为 3.10 以上,可 ...
- SpringBoot运行就停止
检查下是不是没有引入springboot-starter-web依赖 <dependency> <groupId>org.springframework.boot</gr ...