原文: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. NERDTree这个插件的用法简介

    事情是这样子的,想做做李治军老师班的操作系统实验,但是Linux上的gedit太简陋了(这个简陋程度堪比Windows环境下的"记事本"),被杨世祺大神嘲笑了.我心想既然在linu ...

  2. HDU_2033——时间加法

    Problem Description HDOJ上面已经有10来道A+B的题目了,相信这些题目曾经是大家的最爱,希望今天的这个A+B能给大家带来好运,也希望这个题目能唤起大家对ACM曾经的热爱.这个题 ...

  3. UVA 11636 - Hello World! 水

    水题,贪心,dp都随意 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,ple ...

  4. 获取程序中无需释放的ViewController

    AppDelegate.h @property (strong, nonatomic) UIViewController *viewController; 在需要用的地方 #define appDel ...

  5. WP独立文件资源字典

    有时候,开发者想把资源字典定义在单独的XAML文件中,在网上找了找,没找到比较详细的,自己弄了许久. 1. 新建xaml资源字典文件,如在根目录下“ResourceDictionary1.xaml”, ...

  6. 【实验 1-2】编写一个简单的 UDP 服务器和 UDPP 客户端程序。程序均为控制台程序窗口。

    1.服务器 #include<winsock2.h> //包含头文件#include<stdio.h>#include<windows.h>#pragma comm ...

  7. sqlserver,执行生成脚本时“引发类型为“System.OutOfMemoryException”的异常”(已解决)

    sqlserver,执行生成脚本时“引发类型为“System.OutOfMemoryException”的异常”(已解决) 出现此错误主要是因为.sql的脚本文件过大(一般都超过100M)造成内存无法 ...

  8. 广播接收者 BroadcastReceiver 示例-2

    BaseActivity /**所有Activity的基类*/ public class BaseActivity extends Activity {     @Override     prote ...

  9. Redis配置不当可导致服务器被控制,已有多个网站受到影响 #通用程序安全预警#

    文章出自:http://news.wooyun.org/6e6c384f2f613661377257644b346c6f75446f4c77413d3d 符合预警中“Redis服务配置不当”条件的服务 ...

  10. 如何改写WebApi部分默认规则

    为什么要改 最近公司在推广SOA框架,第一次正经接触这种技术(之前也有但还是忽略掉吧),感觉挺好,就想自己也折腾一下,实现一个简单的SOA框架 用过mvc进行开发,印象之中WebApi和Mvc好像是一 ...