Windows Mobile使用Shared Memory(共享内存)进行IPC(进程间通信)的开发

简介:

背景

Unix-like系统进行IPC(Inter-process communication)通信,Shared memory是效率最高的,我称之为IPC的王中王。

 

简介

本文讲述在Windows Mobile和Windows Embedded CE下如何使用Shared Memory(共享内存)进行IPC(进程间通信)。演示如何使用Shared Memory共享数据,使用Named Event唤醒其他进程和使用Named Mutex去为共享数据加锁。

 

主要IPC的方法

在Windows Mobile和Windows Embedded CE系统下,主要的IPC方法有以下几种。

方法

通知

数据存储

数据大小

Named events

间接

N/A

N/A

Windows messages

间接

在Message中

很小,只能传输Integer或者使用COPYDATASTRUCT 传输对象

Point-to-point message queues

间接

在Message中

小型,存在boxing和unboxing问题

MSMQ

直接

在Message中

小型,存在boxing和unboxing问题

TCP sockets

直接

直接发送流(stream)

中度

Memory mapped files

N/A

mapped file

中度

Registry

N/A

注册表

中度

File system

N/A

文件

大型

Database

N/A

数据库

大型

WCF

N/A

WCF消息

中度

上述表格参考了Interprocess Communication with the .NET Compact Framework 1.0

 

关于上述的IPC的方法,没有那个最好,选择的时候需要根据具体需求来决定。这篇文章主要关注Named events和Shared Memory。 我之前也写过关于其他IPC方法的文章,可以参考如下:

Windows Message

.NET Compact Framework下的进程间通信之Windows Message

 

MSMQ

WinCe和Windows Mobile下的MSMQ安装

.NET Compact Framework下的进程间通信之MSMQ开发

 

Registry

.NET Compact Framework下注册表导出工具的开发

 

File System

Windows Mobile和Wince下使用TinyXML进行Native C++的开发

 

Database

.NET Compact Framework下SQL CE的使用 (实现了SqlCeHepler的封装SqlCeHepler的测试类,见.NET Compact Framework下的单元测试

Windows Mobile下Native C++访问SqlCe的封装

SQL Server Express和SQL Server Compact的应用

.NET Campact Framework下SQL CE兼容性问题

Windows Mobile下访问Sqlite的Native C++封装

如何压缩SQLite的数据文件

 

还有Point-to-point message queues, TCP sockets等等一部分主题没有写,如果有人希望我总结出来,请留言,我后续会补充进去。

 

Shared Memory的实现

实现的代码主要参考了OpenNETCF的Smart Device Framework

三个关键的类

shared-memory-IPC-3

MemoryMappedFile用于封装共享内存,在Windows Embedded CE下的共享内存是一个Memory Mapped File,也就是一个内存映射文件,在所有进程的都可以访问的内存中映射文件,操作该共享内存就类似于磁盘物理文件。所以继承于Stream,通过流来读写。

NamedMutex是进程级别的锁,在Native C++一般使用CRITICAL_SECTION做锁,而在.NET Compact Framework会使用monitor,微软已经把monitor封装到lock关键字中了,注意这个lock不是函数,是C#语言内嵌关键字。lock和Monitor等价。

关于lock和CRITICAL_SECTION的使用请参考下面文章。

Windows Mobile使用.NET Compact Framework开发多线程程序

Windows Mobile使用Native C++开发多线程程序

那么,既然有了lock和CRITICAL_SECTION为什么还需要Mutex呢,从性能来说Mutex的效率比Monitor也就是lock要低,所以我一般会使用lock而不是Mutex,但是lock不能支持跨进程加锁,所以在这个case,我使用了Mutex。

.NET Compact Framework本身就提供了一个Mutex的类,可惜只是支持无名Mutex。Mutex分为命名Mutex和无名Mutex,无名的Mutex只能在同一个进程内部使用,不能跨进程使用,所以这里封装了个NamedMutex来支持命名Mutex,从而支持跨进程的锁操作。

EventWaitHandle是通知Event。.NET Compact Framework本身封装了AutoResetEvent和ManualResetEvent,但是他们都不支持跨进程,所以封装了EventWaitHandle来实现跨进程的Event通知。

 

SharedMemoryWriter

SharedMemoryWriter负责往共享内存写数据。

shared-memory-IPC-1

private void StartSharedMemoryWriting()
{
MemoryMappedFile mmf = MemoryMappedFile.CreateInMemoryMap("SharedMemoryBlock");
int i = 100;
while (started)
{
string s = "SharedMemory:" + i.ToString();
UpdateMessageList(s);
byte[] dataBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(s);

// Wait until it is safe to enter.
mutex.WaitOne();
try
{
mmf.Position = 0;
mmf.Write(dataBuffer, 0, dataBuffer.Length);
}
finally
{
// Release the Mutex.
mutex.ReleaseMutex();
}
// Raise the event
namedEvent.Set();

++i;
if (i > 999)
{
i = 100;
}
System.Threading.Thread.Sleep(500);
}
mmf.Close();
}

生成系统唯一命名的共享内存,在这个例子中使用了SharedMemoryBlock。每次写共享内存的时候都通过Named Mutex对该内存加锁。当写完毕后通过Named Event通知SharedMemoryReader(读共享内存)的进程。

 

SharedMemoryReader

SharedMemoryReader负责读取共享内存的数据。

shared-memory-IPC-2

private void StartSharedMemoryReading()
{
MemoryMappedFile mmf = MemoryMappedFile.CreateInMemoryMap("SharedMemoryBlock");
byte[] dataBuffer = new byte[1024];
while (started)
{
if (namedEvent.WaitOne())
{
if (!started)
{
break;
}
namedEvent.Reset();

// Wait until it is safe to enter.
if (mutex.WaitOne())
{
try
{
mmf.Position = 0;
mmf.Read(dataBuffer, 0, 50);
}
finally
{
// Release the Mutex.
mutex.ReleaseMutex();
}
}
string s = System.Text.ASCIIEncoding.ASCII.GetString(dataBuffer, 0, 50);
UpdateMessageList(s);
}
}
mmf.Close();
}

打开同样名字(SharedMemoryBlock)的共享内存,这个进程会挂起直到收到Named Event的消息,每次读取的时候都需要使用Named Mutex来加锁。

 

源代码:http://files.cnblogs.com/procoder/SharedMemoryDemo.rar

环境: Windows Mobile 5 PPC + .NET Compact Framework 2.0 


    本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2010/03/25/Windows-Mobile-Shared-Memory.html,如需转载请自行联系原作者


相关文章
|
11月前
|
消息中间件 存储 网络协议
从零开始掌握进程间通信:管道、信号、消息队列、共享内存大揭秘
本文详细介绍了进程间通信(IPC)的六种主要方式:管道、信号、消息队列、共享内存、信号量和套接字。每种方式都有其特点和适用场景,如管道适用于父子进程间的通信,消息队列能传递结构化数据,共享内存提供高速数据交换,信号量用于同步控制,套接字支持跨网络通信。通过对比和分析,帮助读者理解并选择合适的IPC机制,以提高系统性能和可靠性。
1378 14
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第7天】麒麟系统mate-indicators进程占用内存过高问题解决
1357 2
|
11月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
795 20
|
12月前
|
运维 监控 Ubuntu
【运维】如何在Ubuntu中设置一个内存守护进程来确保内存不会溢出
通过设置内存守护进程,可以有效监控和管理系统内存使用情况,防止内存溢出带来的系统崩溃和服务中断。本文介绍了如何在Ubuntu中编写和配置内存守护脚本,并将其设置为systemd服务。通过这种方式,可以在内存使用超过设定阈值时自动采取措施,确保系统稳定运行。
424 4
|
12月前
|
C语言 开发者 内存技术
探索操作系统核心:从进程管理到内存分配
本文将深入探讨操作系统的两大核心功能——进程管理和内存分配。通过直观的代码示例,我们将了解如何在操作系统中实现这些基本功能,以及它们如何影响系统性能和稳定性。文章旨在为读者提供一个清晰的操作系统内部工作机制视角,同时强调理解和掌握这些概念对于任何软件开发人员的重要性。
|
12月前
|
Linux 调度 C语言
深入理解操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅,从进程管理的基本概念出发,逐步探索到内存管理的高级技巧。我们将通过实际代码示例,揭示操作系统如何高效地调度和优化资源,确保系统稳定运行。无论你是初学者还是有一定基础的开发者,这篇文章都将为你打开一扇了解操作系统深层工作原理的大门。
153 4
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
308 6
|
C# Windows
【Azure App Service】在App Service for Windows上验证能占用的内存最大值
根据以上测验,当使用App Service内存没有达到预期的值,且应用异常日志出现OutOfMemory时,就需要检查Platform的设置是否位64bit。
206 11
|
算法 调度 开发者
深入理解操作系统:从进程管理到内存分配
本文旨在为读者提供一个深入浅出的操作系统知识之旅,从进程管理的基础概念出发,探索内存分配的策略与技巧。我们将通过实际代码示例,揭示操作系统背后的逻辑与奥秘,帮助读者构建起对操作系统工作原理的直观理解。文章不仅涵盖理论知识,还提供实践操作的指导,使读者能够将抽象的概念转化为具体的技能。无论你是初学者还是有一定基础的开发者,都能在这篇文章中找到有价值的信息和启发。
|
算法 调度 C++
深入理解操作系统:从进程管理到内存分配
【10月更文挑战第42天】本文将带你进入操作系统的神秘世界,探索其核心概念和关键技术。我们将从进程管理开始,了解操作系统如何协调和管理多个程序的运行;然后,我们将深入研究内存分配,看看操作系统如何有效地分配和管理计算机的内存资源。通过这篇文章,你将获得对操作系统工作原理的深入理解,并学会如何编写高效的代码来利用这些原理。