千家信息网

C#.Net通信共享内存映射文件是什么

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要讲解了"C#.Net通信共享内存映射文件是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C#.Net通信共享内存映射文件是什么"吧!节
千家信息网最后更新 2026年11月02日C#.Net通信共享内存映射文件是什么

这篇文章主要讲解了"C#.Net通信共享内存映射文件是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C#.Net通信共享内存映射文件是什么"吧!

节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。

内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作系统中地位相当。实际上,任何想要共享数据的通信模型都会在幕后使用它。

内存映射文件究竟是个什么?

内存映射文件允许你保留一块地址空间,然后将该物理存储映射到这块内存空间中进行操作。物理存储是文件管理,而内存映射文件是操作系统级内存管理。

优势:

1.访问磁盘文件上的数据不需执行I/O操作和缓存操作(当访问文件数据时,作用尤其显著);

2.让运行在同一台机器上的多个进程共享数据(单机多进程间数据通信效率最高);

利用文件与内存空间之间的映射,应用程序(包括多个进程)可以通过直接在内存中进行读写来修改文件。.NET Framework 4 用托管代码按照本机Windows函数访问内存映射文件的方式来访问内存映射文件,管理 Win32 中的内存映射文件。

有两种类型的内存映射文件:

  • 持久内存映射文件

持久文件是与磁盘上的源文件关联的内存映射文件。在最后一个进程使用完此文件后,数据将保存到磁盘上的源文件中。这些内存映射文件适合用来处理非常大的源文件。

  • 非持久内存映射文件

非持久文件是未与磁盘上的源文件关联的内存映射文件。当最后一个进程使用完此文件后,数据将丢失,并且垃圾回收功能将回收此文件。这些文件适用于为进程间通信(IPC) 创建共享内存。

1)在多个进程之间进行共享(进程可通过使用由创建同一内存映射文件的进程所指派的公用名来映射到此文件)。

2)若要使用一个内存映射文件,则必须创建该内存映射文件的完整视图或部分视图。还可以创建内存映射文件的同一部分的多个视图,进而创建并发内存。为了使两个视图能够并发,必须基于同一内存映射文件创建这两个视图。

3)如果文件大于应用程序用于内存映射的逻辑内存空间(在 32 位计算机上为2GB),则还需要使用多个视图。

有两种类型的视图:流访问视图和随机访问视图。使用流访问视图可对文件进行顺序访问;在使用持久文件时,随机访问视图是首选方法。

.Net 共享内存 内存映射文件原理

通过操作系统的内存管理器访问的,因此会自动将此文件分隔为多个页,并根据需要对其进行访问。您不需要自行处理内存管理。如下图:

C# .Net 共享内存 演示代码

   //持久内存映射文件:基于现有文件创建一个具有指定公用名的内存映射文件    using (var mmf = MemoryMappedFile.CreateFromFile(@"c:\内存映射文件.data", FileMode.Open, "公用名"))    {        //通过指定的 偏移量和大小 创建内存映射文件视图服务器        using (var accessor = mmf.CreateViewAccessor(offset, length)) //偏移量,可以控制数据存储的内存位置;大小,用来控制存储所占用的空间        {            //Marshal提供了一个方法集,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法。            int size = Marshal.SizeOf(typeof(char));            //修改内存映射文件视图            for (long i = 0; i < length; i += size)            {                char c= accessor.ReadChar(i);                accessor.Write(i, ref c);            }        }    }    //另一个进程或线程可以,在系统内存中打开一个具有指定名称的现有内存映射文件    using (var mmf = MemoryMappedFile.OpenExisting("公用名"))    {        using (var accessor = mmf.CreateViewAccessor(4000000, 2000000))        {            int size = Marshal.SizeOf(typeof(char));            for (long i = 0; i < length; i += size)            {                char c = accessor.ReadChar(i);                accessor.Write(i, ref c);            }        }    }
//非持久内存映射文件:未映射到磁盘上的现有文件的内存映射文件    using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 10000))    {        bool mutexCreated;        //进程间同步        Mutex mutex = newMutex(true, "testmapmutex", out mutexCreated);        using (var stream = mmf.CreateViewStream()) //创建文件内存视图流 基于流的操作        {            var writer = newBinaryWriter(stream);            writer.Write(1);        }        mutex.ReleaseMutex();        Console.WriteLine("Start Process B and press ENTER to continue.");        Console.ReadLine();        mutex.WaitOne();        using (MemoryMappedViewStream stream = mmf.CreateViewStream())        {            var reader = newBinaryReader(stream);            Console.WriteLine("Process A says: {0}", reader.ReadBoolean());            Console.WriteLine("Process B says: {0}", reader.ReadBoolean());        }        mutex.ReleaseMutex();    }    using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))    {         Mutex mutex = Mutex.OpenExisting("testmapmutex");        mutex.WaitOne();       using (var stream = mmf.CreateViewStream(1, 0))//注意这里的偏移量        {            var writer = newBinaryWriter(stream);            writer.Write(0);        }        mutex.ReleaseMutex();    }

C# .Net 进程间通信共享内存

完整示例:C#共享内存非持久化方式通讯的例子,通讯时的线程和进程控制也没有问题。

  • 先启动消息服务IMServer_Message,

  • 再启动状态服务IMServer_State,

  • IMServer_Message回车一次(创建共享内存公用名和公用线程锁,并视图流方式写共享内存),

  • IMServer_State回车一次(获取共享内存并视图流方式写、视图访问器写入结构体类型)

  • 并立刻IMServer_Message再回车一次(读取刚刚写入的信息),

  • 观察IMServer_State屏显变化并等待(线程锁)约5s(线程锁被释放)后

  • 在IMServer_Message上观察屏显(显示刚刚写入共享内存的信息)

IMServer_Message.exe 代码

using System;using System.IO;using System.IO.MemoryMappedFiles;using System.Runtime.InteropServices;using System.Threading;namespace IMServer_Message{    ///     /// 用于共享内存方式通信的 值类型 结构体    ///     public struct ServiceMsg    {        public int Id;        public long NowTime;    }    internal class Program    {        private static void Main(string[] args)        {            Console.Write("请输入共享内存公用名(默认:testmap):");            string shareName = Console.ReadLine();            if (string.IsNullOrEmpty(shareName))                shareName = "testmap";            using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen(shareName, 1024000,MemoryMappedFileAccess.ReadWrite))            {                bool mutexCreated;                //进程间同步                var mutex = new Mutex(true, "testmapmutex", out mutexCreated);                using (MemoryMappedViewStream stream = mmf.CreateViewStream()) //创建文件内存视图流                {                    var writer = new BinaryWriter(stream);                    for (int i = 0; i < 5; i++)                    {                        writer.Write(i);                        Console.WriteLine("{0}位置写入流:{0}", i);                    }                }                mutex.ReleaseMutex();                Console.WriteLine("启动状态服务,按【回车】读取共享内存数据");                Console.ReadLine();                mutex.WaitOne();                using (MemoryMappedViewStream stream = mmf.CreateViewStream())                {                    var reader = new BinaryReader(stream);                    for (int i = 0; i < 10; i++)                    {                        Console.WriteLine("{1}位置:{0}", reader.ReadInt32(), i);                    }                }                using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor(1024, 10240))                {                    int colorSize = Marshal.SizeOf(typeof (ServiceMsg));                    ServiceMsg color;                    for (int i = 0; i < 50; i += colorSize)                    {                        accessor.Read(i, out color);                        Console.WriteLine("{1}\tNowTime:{0}", new DateTime(color.NowTime), color.Id);                    }                }                mutex.ReleaseMutex();            }            Console.WriteLine("测试: 我是 即时通讯 - 消息服务 我启动啦!!!");            Console.ReadKey();        }    }}

IMServer_State.exe代码

using System;using System.IO;using System.IO.MemoryMappedFiles;using System.Runtime.InteropServices;using System.Threading;namespace IMServer_State{    ///     /// 用于共享内存方式通信的 值类型 结构体    ///     public struct ServiceMsg    {        public int Id;        public long NowTime;    }    internal class Program    {        private static void Main(string[] args)        {            Console.Write("请输入共享内存公用名(默认:testmap):");            string shareName = Console.ReadLine();            if (string.IsNullOrEmpty(shareName))                shareName = "testmap";            using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen(shareName, 1024000,MemoryMappedFileAccess.ReadWrite))            {                Mutex mutex = Mutex.OpenExisting("testmapmutex");                mutex.WaitOne();                using (MemoryMappedViewStream stream = mmf.CreateViewStream(20, 0)) //注意这里的偏移量                {                    var writer = new BinaryWriter(stream);                    for (int i = 5; i < 10; i++)                    {                        writer.Write(i);                        Console.WriteLine("{0}位置写入流:{0}", i);                    }                }                using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor(1024, 10240))                {                    int colorSize = Marshal.SizeOf(typeof (ServiceMsg));                    var color = new ServiceMsg();                    for (int i = 0; i < colorSize*5; i += colorSize)                    {                        color.Id = i;                        color.NowTime = DateTime.Now.Ticks;                        //accessor.Read(i, out color);                        accessor.Write(i, ref color);                        Console.WriteLine("{1}\tNowTime:{0}", new DateTime(color.NowTime), color.Id);                        Thread.Sleep(1000);                    }                }                Thread.Sleep(5000);                mutex.ReleaseMutex();            }            Console.WriteLine("测试: 我是 即时通讯 - 状态服务 我启动啦!!!");            Console.ReadKey();        }    }}

感谢各位的阅读,以上就是"C#.Net通信共享内存映射文件是什么"的内容了,经过本文的学习后,相信大家对C#.Net通信共享内存映射文件是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

内存 文件 视图 进程 通信 数据 公用 类型 托管 多个 方式 服务 代码 磁盘 空间 线程 管理 位置 方法 系统 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖南永感互联网科技有限公司 金诺互联网科技 互联网科技公司官网 互联网高科技企业 大白互联网科技 互联网科技视频素材 互联网科技公司做什么 须眉科技是互联网公司吗 互联网对科技的发展 厦门比较好的科技互联网公司 智腾互联网科技有限公司 阿大互联网科技有限公司 互联网科技的全部知识 高科技互联网发展前景如何 南博望互联网科技有限公司 无锡工业互联网科技有限公司 2021互联网科技公司排名 山东大美朱楼互联网科技有限公司 西安有哪些互联网高科技企业 科技信息时代互联网发展 智能科技公司是互联网公司吗 科技类互联网 没上市的科技互联网公司 九亚互联网科技 互联网科技公司有哪些 哈尔滨秒房互联网科技有限公司 银川新华互联网科技职业技术培训学校图片 现代互联网科技股 亳州好赞互联网科技有限公司 互联网硬科技公司
0