我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

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

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

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

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

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

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

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

优势:

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

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

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

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

  • 持久内存映射文件

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

  • 非持久内存映射文件

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

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

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

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

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

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

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

C#.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{    /// <summary>    /// 用于共享内存方式通信的 值类型 结构体    /// </summary>    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{    /// <summary>    /// 用于共享内存方式通信的 值类型 结构体    /// </summary>    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通信共享内存映射文件是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

这篇文章主要讲解了“C#.Net通信共享内存映射文件是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#.Net通信共享内存映射文件是什么”吧!节点通信存在两种模型:共享内存(Share
2023-06-30

怎么在c#中通过内存映射共享文件

本篇文章给大家分享的是有关怎么在c#中通过内存映射共享文件,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。App1代码:using System;using System.Col
2023-06-14

Linux的共享内存与tmpfs文件系统是什么

本篇内容介绍了“Linux的共享内存与tmpfs文件系统是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言共享内存主要用于进程间通信,
2023-06-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录