首页 > 系统相关 >C# 进程间通过内存映射文件通信

C# 进程间通过内存映射文件通信

时间:2023-07-10 22:24:03浏览次数:51  
标签:stream 映射 C# void VariableProxy memoryMappedFile 内存 new public

内存映射文件(Memory-mapped files)是一种很好的进程间通信方式,它暴露了底层的细节,具有很强的扩展性以及性能。

这里展示一个利用内存映射文件制作的 变量同步工具。

该工具当前存在的问题是:

  1. 每次会同步变量的所有字段,不能针对某个字段进行同步。
  2. 没有使用双缓冲,超出64位的字段会出现问题。
  3. 一个类一个文件,没能充分利用文件的空间。

工具代码

public interface ISerializer<T>
    where T :ISerializer<T>
{
    void Serialize(BinaryWriter writer);
    void Deserialize(BinaryReader reader);
}
public class VariableAllocator
{
    public static VariableProxy<T> NewPub<T>() 
        where T : ISerializer<T>,new()
    {
        return NewPub<T>("", 4096);
    }

    public static VariableProxy<T> NewPub<T>(string mapNamePrefix, int capacity) 
        where T: ISerializer<T>,new()
    {
        MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateNew(mapNamePrefix+typeof(T).Name, capacity);

        var publisher = new VariableProxy<T>(memoryMappedFile);

        return publisher;
    }

    public static VariableProxy<T> NewSub<T>() 
        where T: ISerializer<T>,new()
    {
        return NewSub<T>("");
    }

    public static VariableProxy<T> NewSub<T>(string mapNamePrefix)
        where T: ISerializer<T>,new()
    {
        MemoryMappedFile memoryMappedFile = MemoryMappedFile.OpenExisting(mapNamePrefix + typeof(T).Name);

        var publisher = new VariableProxy<T>(memoryMappedFile);

        return publisher;
    }

}
{
public class VariableProxy<T> : VariableProxy
    where T: ISerializer<T>, new()
{

    public VariableProxy(MemoryMappedFile memoryMappedFile) : base(memoryMappedFile)
    {
    }

    public void Publish(T val)
    {
        memoryMappedViewStream.Position = 0;
        val.Serialize(writer);
    }

    public T Subscribe()
    {
        memoryMappedViewStream.Position = 0;
        var val = new T();
        val.Deserialize(reader);
        return val;
    }
}

public class VariableProxy:IDisposable
{
    protected MemoryMappedFile memoryMappedFile;

    protected MemoryMappedViewStream memoryMappedViewStream;

    protected BinaryWriter writer;
    protected BinaryReader reader;


    public VariableProxy(MemoryMappedFile memoryMappedFile)
    {
        this.memoryMappedFile = memoryMappedFile;
        memoryMappedViewStream = memoryMappedFile.CreateViewStream();
        writer = new BinaryWriter(memoryMappedViewStream);
        reader = new BinaryReader(memoryMappedViewStream);
    }

    public void Dispose()
    {
        memoryMappedFile.Dispose();
        memoryMappedViewStream.Dispose();
        writer.Dispose();
        reader.Dispose();
    }

}

变量代码

    public class Player:ISerializer<Player>
    {
        public int Id { get; set; }
        public int Age { get; set; }
        public int Hp { get; set; }

        public void Deserialize(BinaryReader stream)
        {
            Id = stream.ReadInt32();
            Age = stream.ReadInt32();
            Hp = stream.ReadInt32();
        }

        public void Serialize(BinaryWriter stream)
        {
            stream.Write(Id);
            stream.Write(Age);
            stream.Write(Hp);
        }
    }

发送方代码

    class Program
    {
        // Process A:
        static void Main(string[] args)
        {
            Player player = new Player { Id = 1001, Age = 23, Hp = 40000 };

            using (var pub = VariableAllocator.NewPub<Player>())
            {
                while (true)
                {
                    pub.Publish(player);

                    player.Hp -= 1;
                    Thread.Sleep(1000);
                }
            }
        }
    }

接收方代码

    static void Main(string[] args)
    {
        try
        {
            using(var sub = VariableAllocator.NewSub<Player>())
            {

                while (true)
                {
                    Player player = sub.Subscribe();

                    Console.WriteLine($"ID={player.Id} Age={player.Age} HP={player.Hp}");
                }

            }
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("Memory-mapped file does not exist. Run Process A first.");
        }
    }

标签:stream,映射,C#,void,VariableProxy,memoryMappedFile,内存,new,public
From: https://www.cnblogs.com/dewxin/p/17542473.html

相关文章

  • python: sqlalchemy ORM in mysql
     """StudengMaping.pyORM(ObjectRelationalMapping)学生表实体类对象关系映射one-oneone-moremore-onemore-moredate2023-06-23edit:GeovinDu,geovindu,涂聚文ide:PyCharm2023.1python11sqlalchemy2.0.1.6https://docs.sqlalchemy.org/en/20/cor......
  • 解决Docker -v 挂载单文件问题
    问题描述下面命令挂载文件看着没有什么问题吧? dockerrun--namexxxx-p8001:80-v/docker/appsettings.json:/app/appsettings.json-dxxxx:v1.1.0但当我们执行完就会发现文件并没有挂载过来而是给我们创建了一个文件夹 解决方案 官方的建议是挂载文件夹,而不是......
  • async_ensuer_future_add_done_callback
    asyncensuer_future和add_done_callback的用法importosfromloguruimportloggerlogger.add(os.path.join(os.path.dirname(__file__),os.path.basename(__file__).split('.')[0]+'.z.log'))importtimeimportasyncioasyncdefrequest_img......
  • 解决从springboot配置文件application.properties获取中文乱码
    这里因为自带的iso编码格式需要进行如下操作 新增两个文件重写packagecom.java.file.config;importorg.springframework.boot.origin.Origin;importorg.springframework.boot.origin.OriginTrackedValue;importorg.springframework.boot.origin.TextResourceOrigin;......
  • 1002 A+B for Polynomials C++
    Thistime,youaresupposedtofind A+B where A and B aretwopolynomials.InputSpecification:Eachinputfilecontainsonetestcase.Eachcaseoccupies2lines,andeachlinecontainstheinformationofapolynomial:K N1​ aN1​​ N2​ aN2​​ ......
  • 【NSSCTF逆向】【2023题目】《stream》《a_cup_of_tea》
    总览streamRC4base64exe解包pyc反编译a_cup_of_teatea题目stream解法拿到题目是一个exe,先用exeinfo打开看看可以看到这个程序使用python写的,又是exe。所以就是常规的思路,exe解包到pyc文件,再对pyc文件进行反编译先是解包用pyinstxtractor.py里面找到它再来反编......
  • arch linux deepin-wine-wechat
    https://aur.archlinux.org/packages/deepin-wine-wechatmd5sumforWeChatSetup-3.9.0.28.exeshouldbeupdatedto 83c3d37b47147eb29b291a50d488dae3 onthePKGBUILDforthechecktopass. md5sums=('6c4edb108a0593bab7a556a6c9e8a012'        '8......
  • CSS 父元素没有设置高度,子元素如何跟父元素保持一样的高度?
    如上图所示,height属性需要让父元素有高度,所以,h2的::before设置了百分比高度就行不通。样式如下所示:h2{&::before{content:"";display:inline-block;width:0.5rem;height:100%;border-top-right-radius:0.5rem;border-bottom-left-......
  • vite和webpack的区别
    Vite和Webpack都是现代前端开发中的常见打包工具,五个主要区别:1.开发模式不同Webpack在开发模式下依然会对所有模块进行打包操作,虽然提供了热更新,但大型项目中依然可能会出现启动和编译缓慢的问题;而Vite则采用了基于ESModule的开发服务器,只有在需要时才会编译对应的模块,大幅......
  • Istio与Mcp Server服务器讲解与搭建演示
    01Istio与外部注册中心Istio为何需要对接外部注册中心Istio对Kubernetes具有较强的依赖性:1.服务发现就是基于Kubernetes实现的,如果要使用Istio,首先需要迁移到Kubernetes上,并使用Kubernetes的服务注册发现机制。2.对于大量现存的微服务项目来说,这个前提条件并不成立。对......