C#下的进程间的通讯 -- 共享内存--内存互斥控制

转载 2011年01月11日 17:36:00

  C#下的进程间的通讯 -- 共享内存篇 收藏
 【摘要】
这篇文章早就想发了,可是一直没有时间整理,今天总算发上来了。

上次发了利用发消息实现的C#进程间的通讯,这次又使用共享内存了,他们应用范围是不同的,共享内存适用于共享大量数据的情况。
本文章利用了前面的一篇.net 1.1 下实现的信号量的类,在.net 1.1 下实现,如果在.net 2.0 下实现的话就用不到我的那个信号量的类了,因为这个类在.net 2.0是提供的。

【全文】

首先还是定义非托管调用,如下:


const int INVALID_HANDLE_VALUE = -1;
const int PAGE_READWRITE = 0x04;
  //共享内存
  [DllImport("Kernel32.dll",EntryPoint="CreateFileMapping")]
  private static extern IntPtr CreateFileMapping(IntPtr hFile, //HANDLE hFile,
   UInt32 lpAttributes,//LPSECURITY_ATTRIBUTES lpAttributes,  //0
   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);
然后分别在AB两个进程中定义如下两个信号量及相关变量;

  private Semaphore m_Write;  //可写的信号
  private Semaphore m_Read;  //可读的信号
  private IntPtr handle;     //文件句柄
  private IntPtr addr;       //共享内存地址
  uint mapLength;            //共享内存长

定义这两个信号量是为读写互斥用的。
在A进程中创建共享内存:

m_Write = new Semaphore(1,1,"WriteMap");
m_Read = new Semaphore(0,1,"ReadMap");
mapLength = 1024;
IntPtr hFile = new IntPtr(INVALID_HANDLE_VALUE);  
handle = CreateFileMapping(hFile,0,PAGE_READWRITE,0,mapLength,"shareMemory");
addr = MapViewOfFile(handle,FILE_MAP_ALL_ACCESS,0,0,0);
然后再向共享内存中写入数据:

m_Write.WaitOne();
byte[] sendStr = Encoding.Default.GetBytes(txtMsg.Text + '/0');
//如果要是超长的话,应另外处理,最好是分配足够的内存
if(sendStr.Length < mapLength)
      Copy(sendStr,addr);
m_Read.Release();

这是在一个单独的方法中实现的,可多次调用,但受信号量的控制。其中txtMsg是一个文本框控件,实际中可用任意字符串,加最后的'/0'是为了让在共享内存中的字符串有一个结束符,否则在内存中取出时是以'/0'为准的,就会出现取多的情况。
Copy方法的实现如下:

static unsafe void Copy(byte[] byteSrc,IntPtr dst)
  {
   fixed (byte* pSrc = byteSrc)
   {
    byte* pDst = (byte*)dst;
    byte* psrc = pSrc;
    for(int i=0;i<byteSrc.Length;i++)
    {
     *pDst = *psrc;
     pDst++;
     psrc ++;
    }
   }
  }
注意unsafe 关键字,在编译时一定要打开非安全代码开关。
最后不要忘了在A进程中关闭共享内存对象,以免内存泄露。

   UnmapViewOfFile(addr);
   CloseHandle(handle);

要在B进程中读取共享内存中的数据,首先要打开共享内存对象:

m_Write = Semaphore.OpenExisting("WriteMap");
m_Read = Semaphore.OpenExisting("ReadMap");
handle = OpenFileMapping(0x0002,0,"shareMemory");
读取共享内存中的数据:

   m_Read.WaitOne();
   string str = MapViewOfFile(handle,FILE_MAP_ALL_ACCESS,0,0,0);
   txtMsg.Text = str;
   m_Write.Release();
这里获取了字符串,如果要获取byte数组,请参考上面的Copy函数实现。
=================================================================================================
来源:http://www.x2blog.cn/jinhong618/21581.html


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dhz123/archive/2008/07/25/2708883.aspx

邮件发送(C#)

C#编写发送邮件到163,或QQ
  • 2017年06月25日 15:50

进程间通信:共享内存(代码实现)

共享内存:1.共享内存就是允许两个不相关的进程访问同一个逻辑内存;                     2.共享内存是在两个正在运行的进程之间共享和传递数据的一种最有效的方式;        ...
  • wangiijing
  • wangiijing
  • 2016-07-06 18:17:36
  • 4499

C++ 进程间共享内存-实现进程同步

参考原文:http://blog.csdn.net/liuguangsh/article/details/52130177// 一,读共享内存源代码 // //ShareMemory_Read.cpp...
  • sxlsxl119
  • sxlsxl119
  • 2017-10-16 09:29:16
  • 299

进程间通信之共享内存

何为共享内存 共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段...
  • qq_33724710
  • qq_33724710
  • 2016-09-02 14:47:30
  • 950

.net4.0多<em>进程间共享内存</em>实现通信

.net4.0新增<em>内存共享</em>功能,从而很方便的实现了多<em>进程间</em>通信。... .net4.0新增<em>内存共享</em>功能,从而很方便的实现了多<em>进程间</em>通信。综合评分:4 收藏(1)评论(<em>23</em>)举报 ...
  • 2018年04月13日 00:00

【共享内存】利用MFC写的进程间通信——内存共享

MFC写的程序,自己对共享内存的一点理解,赶紧记下来方便今后对照、修改。...
  • yzt33
  • yzt33
  • 2015-03-18 15:31:10
  • 1485

进程间通信系列 之 共享内存及其实例

顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。...
  • iamonlyme
  • iamonlyme
  • 2013-11-13 20:04:52
  • 2971

进程间通信_共享内存类_C++实现

头文件: [cpp:nogutter] view plaincopyprint? /****************************************************...
  • chinabinlang
  • chinabinlang
  • 2012-10-22 13:53:54
  • 2370

C++使用共享内存实现进程间通信

C++使用共享内存实现进程间通信 文件映射是一种实现进程间单向或双向通信的机制。它允许两个或多个本地进程间相互通信。为了共享文件或内存,所有的进程必须使用相同的文件映射的名字或是句柄。 为了实现共...
  • joejames
  • joejames
  • 2014-07-27 11:00:56
  • 5666

共享内存,多进程间共享结构体

共享内存 中 存结构体,多线程多进程间实现共享。
  • liukang325
  • liukang325
  • 2014-09-11 16:32:26
  • 3115
收藏助手
不良信息举报
您举报文章: C#下的进程间的通讯 -- 共享内存--内存互斥控制
举报原因:
原因补充:

(最多只允许输入30个字)