架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 1960|回复: 1

[技巧] 【转】关于 Shared Memory 的两三事

[复制链接]
发表于 2024-7-23 14:50:48 | 显示全部楼层 |阅读模式
参与古老系统的搬迁工程,其中使用Shared Memory 实现跨Process 沟通(例如:ASP.NET 呼叫Window Service),也因而被迫了解这门对.NET 开发者偏冷门的技术,特笔记备忘。

【Shared Memory 是什么?】
跨Process 沟通有个术语,Interprocess Communictaion(IPC),在Windows 平台有以下选择:参考:超链接登录可见。

Clipboard
程式A 将内容贴进剪贴簿,程式B 自剪贴簿取出内容。
COM
OLE 复合文件(Compound Document)让Word 文件可以内嵌Excel 工作表,点两下还能叫出Excel 进行编辑, OLE 的基础为COM 元件技术。
Data Copy
程序A 向程式B 依约定的格式内容传送WM_COPYDATA 讯息
DDE
DDE 是一种允许不同应用程式交换不同格式资料的通讯协定,可视为剪贴簿的沿伸,除了一次性抛转,还能持续传输资料。 (效能相对差,已不建议使用)
File Mapping
File Mapping 意指将档案模拟成Process 中的一块记忆体,当多个应用程式间透过共用File Mapping 交换资料,称之为Named Shared Memory,在各种IPC 方法中效能最佳,但必须透过Mutex等同步机制防止读写冲突。
Mailslots
单向沟通,Mailslot Client 送讯息给Mailslot Server,讯息在Server 读取后删除,支援跨机器传送,还可一对多广播。 (广播讯息长度限制400 bytes,一对一传输时讯息长度则由Mailslot Server 建立时决定)
Pipes
双向传输,分为Anonymous Pipe 及Named Pipe。 Anonymous Pipe 一般用于父程序与子程序间的标准输入/输出导向,双向沟通要建两条Pipe,不能跨网路且限于有从属关系的Process;Named Pipe 则可用于任意Process 间交换资料,并支援跨网路Process 间传输。
RPC
Remote Procedure Call(RPC) 允许应用程式呼叫其他应用程式提供的函式功能,并可跨网路呼叫。 Windows RPC 符合ISO DCE 标准,支援跨作业系统系统整合。
Windows Sockets
基于TCP/IP 或其他网路协定制订的抽象通讯介面,底层透过网路连线进行资料交换。
Shared Memory 是C/C++ 开发者常用的资料交换方式( Google 可以查到很多在Linux 用Shared Memory 实现IPC 的范例),故C/C++ 开发者在Windows 平台也常选择它做为沟通管道。

【Shared Memory 实作练习】
虽然用的人较少,但.NET 内建System.IO.MemoryMappedFiles 命名空间,要玩Shared Memory 不是难事,几乎跟操作档案没什么两样,只要有FileStream 相关操作经验很快就上手,参考MSDN 范例,我写了小程式练习。超链接登录可见。

我写了两只程式,ProcessA 透过MemoryMappedFile.CreateNew() 建立大小为1024 Bytes 的空间,与另一只ProcessB 练习传接球。由于1024 Bytes 两只程式共用,我将前512 规划为ProcessA 写入ProcessB 读取,后512 则是ProcessB 写ProcessA 读,程式中使用CreateViewStream 传入起始位址及长度指向自己专属的区域。为了避免ProcessA 及ProcessB 存取MemoryMappedFile 时出现读写冲突,我使用Mutex 锁定控管单一时间只有一个Process 可以存取MemoryMappedFile。测试过程为ProcessA 建立MemoryMappedFile,写入讯息字串–> ProcessB 读取讯息字串并写入回应字串–> ProcessA 读取回应字串,结束。

ProcessA 程式如下:

ProcessB 程式如下:

测试成功!

4093-9b56-o.gif

【补充技巧】

1.如何检视Windows 目前已开启的MemoryMappedFile?

SystemInternals 有个AccessChk 工具能列出Windows 所有可存取的档案、资料夹、Registry、物件以及Windows 服务。而MemoryMappedFile 属于一种Windows 物件,使用以下指令可列出所有物件并存档
accesschk -osv > e:\objList.txt
在其中寻找MemoryMappedFile 名称,若存在可看到类似以下记录:
\Sessions\1\BaseNamedObjects\DARKTHREAD
  Type: Section
  Medium Mandatory Level (Default) [No-Write-Up]
  RW NT AUTHORITY\SYSTEM
    SECTION_ALL_ACCESS
  RW DOMAIN\UserName
    SECTION_ALL_ACCESS
  RW DOMAIN\UserName-S-1-5-5-0-954410
    SECTION_ALL_ACCESS

AccessChk 工具下载:超链接登录可见。

2.MemoryMappedFile 预设是开在使用者的Session 中,预设无法跨Session 使用。例如:两个分属不同AppPool 的ASP.NET 若执行身分不同,即使MemoryMappedFile 名称相同也是各自一份,故运用时需确认沟通双方使用的执行身分相同。

3.若要跨不同执行身分沟通,MemoryMappedFile 可命名为"Global\ Filename "(注意Global 大小写有别,我踩到误写为GLOBAL 路径无效的雷),如此可跨执行身分存取。
但需要注意,Session 0 (Windows Service)以外的Process 需要具有SeCreateGlobalPrivilege 权限才能建立Global\… MemoryMappedFile。 (MSDN文件)
关于Session 0,可参考对岸MVP 的这篇文章-穿透Session 0 隔离(一)(超链接登录可见。)里面有蛮详细的介绍。

转载自:超链接登录可见。





上一篇:Angular 18 图片静态资源加载问题
下一篇:简单了解 Bootstrap 5 文件内容结构
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2024-8-10 21:36:57 | 显示全部楼层
.NET/C# 基于 Mutex、MemoryMappedFile 实现程序单例
https://www.itsvse.com/thread-10808-1-1.html
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2025-6-15 21:39

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表