原文:C# 进程间通信(共享内存)

进程间通信的方式有很多,常用的方式有:

1.共享内存(内存映射文件,共享内存DLL)。

2.命名管道和匿名管道。

3.发送消息

本文是记录共享内存的方式进行进程间通信,首先要建立一个进程间共享的内存地址,创建好共享内存地址后,一个进程向地址中写入数据,另外的进程从地址中读取数据。

在数据的读写的过程中要进行进程间的同步。

进程间数据同步可以有以下的方式

1. 互斥量Mutex

2. 信号量Semaphore

3. 事件Event

本文中进程间的同步采用 信号量Semaphore的方式同步思想类似于操作系统中生产者和消费者问题的处理方式。

在A进程中创建共享内存,并开启一个线程用来读取B进程向共享内存中写入的数据,定义两个信号量进行读写互斥同步

A进程中的程序代码

using System;

using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Threading;using System.Diagnostics;namespace AppOne{    public partial class AppOneMain : Form    {        const int INVALID_HANDLE_VALUE = -;        const int PAGE_READWRITE = 0x04;        [DllImport("User32.dll")]        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);        [DllImport("User32.dll")]        private static extern bool SetForegroundWindow(IntPtr hWnd);        //共享内存        [DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]        private static extern IntPtr CreateFileMapping(IntPtr hFile, //HANDLE hFile,         UInt32 lpAttributes,//LPSECURITY_ATTRIBUTES lpAttributes,  //         UInt32 flProtect,//DWORD flProtect         UInt32 dwMaximumSizeHigh,//DWORD dwMaximumSizeHigh,         UInt32 dwMaximumSizeLow,//DWORD dwMaximumSizeLow,         string lpName//LPCTSTR lpName         );        [DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]        private static extern IntPtr OpenFileMapping(         UInt32 dwDesiredAccess,//DWORD dwDesiredAccess,         int bInheritHandle,//BOOL bInheritHandle,         string lpName//LPCTSTR lpName         );        const int FILE_MAP_ALL_ACCESS = 0x0002;        const int FILE_MAP_WRITE = 0x0002;        [DllImport("Kernel32.dll", EntryPoint = "MapViewOfFile")]        private static extern IntPtr MapViewOfFile(         IntPtr hFileMappingObject,//HANDLE hFileMappingObject,         UInt32 dwDesiredAccess,//DWORD dwDesiredAccess         UInt32 dwFileOffsetHight,//DWORD dwFileOffsetHigh,         UInt32 dwFileOffsetLow,//DWORD dwFileOffsetLow,         UInt32 dwNumberOfBytesToMap//SIZE_T dwNumberOfBytesToMap         );        [DllImport("Kernel32.dll", EntryPoint = "UnmapViewOfFile")]        private static extern int UnmapViewOfFile(IntPtr lpBaseAddress);        [DllImport("Kernel32.dll", EntryPoint = "CloseHandle")]        private static extern int CloseHandle(IntPtr hObject);        private Semaphore m_Write;  //可写的信号        private Semaphore m_Read;  //可读的信号        private IntPtr handle;     //文件句柄        private IntPtr addr;       //共享内存地址        uint mapLength;            //共享内存长        //线程用来读取数据        Thread threadRed;        public AppOneMain()        {            InitializeComponent();            init();        }                    ///<summary>/// 初始化共享内存数据 创建一个共享内存        ///</summary>privatevoid init()        {            m_Write = new Semaphore(, , "WriteMap");//开始的时候有一个可以写            m_Read = new Semaphore(, , "ReadMap");//没有数据可读            mapLength = ;            IntPtr hFile = new IntPtr(INVALID_HANDLE_VALUE);            handle = CreateFileMapping(hFile, , PAGE_READWRITE, , mapLength, "shareMemory");            addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, , , );            //handle = OpenFileMapping(0x0002, 0, "shareMemory");            //addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);            threadRed = new Thread(new ThreadStart(ThreadReceive));            threadRed.Start();        }        /// <summary>        /// 线程启动从共享内存中获取数据信息         /// </summary>        private void ThreadReceive()        {            myDelegate myI = new myDelegate(changeTxt);            while (true)            {                try                {                    //m_Write = Semaphore.OpenExisting("WriteMap");                    //m_Read = Semaphore.OpenExisting("ReadMap");                    //handle = OpenFileMapping(FILE_MAP_WRITE, 0, "shareMemory");                    //读取共享内存中的数据:                    //是否有数据写过来                    m_Read.WaitOne();                    //IntPtr m_Sender = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);                    byte[] byteStr = new byte[];                    byteCopy(byteStr, addr);                    string str = Encoding.Default.GetString(byteStr, , byteStr.Length);                   /////调用数据处理方法 处理读取到的数据                    m_Write.Release();                }                catch (WaitHandleCannotBeOpenedException)                {                    continue;                    //Thread.Sleep(0);                }            }        }        //不安全的代码在项目生成的选项中选中允许不安全代码        static unsafe void byteCopy(byte[] dst, IntPtr src)        {            fixed (byte* pDst = dst)            {                byte* pdst = pDst;                byte* psrc = (byte*)src;                while ((*pdst++ = *psrc++) != '\0')                    ;            }        }    }}

B进程向共享内存中写入的数据

using System;

using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Threading;namespace AppTwo{    public partial class AppTwoMain : Form    {        const int INVALID_HANDLE_VALUE = -;        const int PAGE_READWRITE = 0x04;        //共享内存        [DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]        private static extern IntPtr CreateFileMapping(IntPtr hFile, //HANDLE hFile,         UInt32 lpAttributes,//LPSECURITY_ATTRIBUTES lpAttributes,  //         UInt32 flProtect,//DWORD flProtect         UInt32 dwMaximumSizeHigh,//DWORD dwMaximumSizeHigh,         UInt32 dwMaximumSizeLow,//DWORD dwMaximumSizeLow,         string lpName//LPCTSTR lpName         );        [DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]        private static extern IntPtr OpenFileMapping(         UInt32 dwDesiredAccess,//DWORD dwDesiredAccess,         int bInheritHandle,//BOOL bInheritHandle,         string lpName//LPCTSTR lpName         );        const int FILE_MAP_ALL_ACCESS = 0x0002;        const int FILE_MAP_WRITE = 0x0002;        [DllImport("Kernel32.dll", EntryPoint = "MapViewOfFile")]        private static extern IntPtr MapViewOfFile(         IntPtr hFileMappingObject,//HANDLE hFileMappingObject,         UInt32 dwDesiredAccess,//DWORD dwDesiredAccess         UInt32 dwFileOffsetHight,//DWORD dwFileOffsetHigh,         UInt32 dwFileOffsetLow,//DWORD dwFileOffsetLow,         UInt32 dwNumberOfBytesToMap//SIZE_T dwNumberOfBytesToMap         );        [DllImport("Kernel32.dll", EntryPoint = "UnmapViewOfFile")]        private static extern int UnmapViewOfFile(IntPtr lpBaseAddress);        [DllImport("Kernel32.dll", EntryPoint = "CloseHandle")]        private static extern int CloseHandle(IntPtr hObject);        private Semaphore m_Write;  //可写的信号        private Semaphore m_Read;  //可读的信号        private IntPtr handle;     //文件句柄        private IntPtr addr;       //共享内存地址        uint mapLength;            //共享内存长        Thread threadRed;        public AppTwoMain()        {            InitializeComponent();            //threadRed = new Thread(new ThreadStart(init));            //threadRed.Start();            mapLength = ;                    }        private void button1_Click(object sender, EventArgs e)        {            try            {                m_Write = Semaphore.OpenExisting("WriteMap");                m_Read = Semaphore.OpenExisting("ReadMap");                handle = OpenFileMapping(FILE_MAP_WRITE, , "shareMemory");                addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, , , );                m_Write.WaitOne();                byte[] sendStr = Encoding.Default.GetBytes(textBox1.Text.ToString() + '\0');                //如果要是超长的话,应另外处理,最好是分配足够的内存                if (sendStr.Length < mapLength)                    Copy(sendStr, addr);                                m_Read.Release();                                            }            catch (WaitHandleCannotBeOpenedException)            {                MessageBox.Show("不存在系统信号量!");                return;            }        }        static unsafe void Copy(byte[] byteSrc, IntPtr dst)        {            fixed (byte* pSrc = byteSrc)            {                byte* pDst = (byte*)dst;                byte* psrc = pSrc;                for (int i = ; i < byteSrc.Length; i++)                {                    *pDst = *psrc;                    pDst++;                    psrc++;                }            }        }   }}

C# 进程间通信(共享内存)的更多相关文章

  1. Linux环境进程间通信: 共享内存

    Linux环境进程间通信: 共享内存 第一部分 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进 ...

  2. linux进程间通信-共享内存

    转载:http://www.cnblogs.com/fangshenghui/p/4039720.html 一 共享内存介绍 共享内存可以从字面上去理解,就把一片逻辑内存共享出来,让不同的进程去访问它 ...

  3. Linux下进程间通信--共享内存:最快的进程间通信方式

    共享内存: 一.概念: 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间. 进程A可以即时看到进程B ...

  4. Linux进程间通信—共享内存

    五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...

  5. Windows进程间通信--共享内存映射文件(FileMapping)--VS2012下发送和接收

    之前以为两个互不相关的程序a.exe b.exe通信就只能通过网络,人家说可以通过发消息,我还深以为不然,对此,我表示万分惭愧. 之前课本上说的进程间通信,有共享内存.管道等之类的,但没有自己操刀写过 ...

  6. Linux 进程间通信 共享内存

    1.特点: 1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝.如管道当在内核空间创建以后,用户空间需要内存  拷贝,需要拷贝数据,所以效率低. 2)为了在多个进 ...

  7. linux 进程间通信 共享内存 shmat

    系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件(这是通过shm ...

  8. linux 进程间通信 共享内存 mmap

    共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反 ...

  9. win32下进程间通信——共享内存

    一.引言     在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换 ...

随机推荐

  1. 笔记:java并发编程实践1

    Java 5.0 adds ConcurrentHashMap, a replacement for synchronized hash-based Map implementations, and ...

  2. HDU_2021——最少RMB问题

    Problem Description 作为杭电的老师,最盼望的日子就是每月的8号了,因为这一天是发工资的日子,养家糊口就靠它了,呵呵但是对于学校财务处的工作人员来说,这一天则是很忙碌的一天,财务处的 ...

  3. 使用python程序监控云服务器的带宽

    将一些不重要的服务迁移到云服务上,有些下载什么的,为了防止带宽超了,python做了一个监控程序.用python3写的,由于和python2有些区别,特记录下来备查. 代码如下: #this is f ...

  4. 聚聚科技---PHP开发笔试题及答案

    1. echo(), print(), print_r()的区别? echo是PHP语言结构, print和print_r是函数.语言结构没有返回值,函数可以有返回值(即便没有用)  . print( ...

  5. Solr集成IK中文分词器

    1.将IKAnalyzer-2012-4x.jar拷贝到example\solr-webapp\webapp\WEB-INF\lib下: 2.在schema.xml文件中添加fieldType: &l ...

  6. OpenSuse下编译MonoDevelop

    当访问Monodevelop.com官网下载的安装包,安装后,发现并不是最新版.在OpenSuse下载的是3.0版本.根据官网的指示,可以自己下载源码进行编译.按官网的指引: 1. $ git clo ...

  7. WEB 开发所用的网站

    常用前端手册: http://caniuse.com/ http://www.w3school.com.cn/ http://www.runoob.com/ http://www.css88.com/ ...

  8. 关于链接target的问题

    <a href="http://www.baidu.com" target="_blank">点击链接</a> target: _bla ...

  9. (转)HiddenField控件的使用

    ASP.NET2.0 HiddenField控件(1)2007-05-12 23:18HiddenField控件顾名思义就是隐藏输入框的服务器控件,它能让你保存那些不需要显示在页面上的且对安全性要求不 ...

  10. (转)VS无法启动调试:“生成下面的模块时,启用了优化或没有调试信息“

    中调试项目遇到错误提示,Visual Studio 2010(或VS2008或VS2005)启动调试的时候,弹出提示信息: 生成下面的模块时,启用了优化或没有调试信息: C:\WINDOWS\Micr ...