在要求输入邮箱的文本域,请填写真实的邮件地址。非真实邮件地址,将收不到回复信息。

C#实现共享内存

C# 清风 675℃ 0评论

共享内存

共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。

C#  调用Win32 系统APi实现共享内存:

public class ShareMem 
{
	[DllImport("user32.dll", CharSet = CharSet.Auto)]
	        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);
	[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
	        public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);
	[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
	        public static extern IntPtr OpenFileMapping(int dwDesiredAccess,[MarshalAs(UnmanagedType.bool)] bool bInheritHandle,string lpName);
	[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
	        public static extern IntPtr MapViewOfFile(IntPtr hFileMapping,uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,uint dwNumberOfBytesToMap);
	[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
	        public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);
	[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
	        public static extern bool CloseHandle(IntPtr handle);
	[DllImport("kernel32", EntryPoint="GetLastError")]
	        public static extern int GetLastError ();
	const int ERROR_ALREADY_EXISTS = 183;
	const int FILE_MAP_COPY = 0x0001;
	const int FILE_MAP_WRITE = 0x0002;
	const int FILE_MAP_READ = 0x0004;
	const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;
	const int PAGE_READONLY = 0x02;
	const int PAGE_READWRITE = 0x04;
	const int PAGE_WRITECOPY = 0x08;
	const int PAGE_EXECUTE = 0x10;
	const int PAGE_EXECUTE_READ = 0x20;
	const int PAGE_EXECUTE_READWRITE = 0x40;
	const int SEC_COMMIT = 0x8000000;
	const int SEC_IMAGE = 0x1000000;
	const int SEC_NOCACHE = 0x10000000;
	const int SEC_RESERVE = 0x4000000;
	const int INVALID_HANDLE_VALUE = -1;
	IntPtr m_hSharedMemoryFile = IntPtr.Zero;
	IntPtr m_pwData = IntPtr.Zero;
	bool m_bAlreadyExist = false;
	bool m_bInit = false;
	long m_MemSize=0;
	public ShareMem() 
	{
	}
	~ShareMem() 
	{
		Close();
	}
	/// <summary>
	/// 初始化共享内存
	/// </summary>
	/// <param name="strName">共享内存名称</param>
	/// <param name="lngSize">共享内存大小</param>
	/// <returns></returns>
	public int Init(string strName, long lngSize) 
	{
		if (lngSize <= 0 || lngSize > 104857600) lngSize = 104857600;
		//0x00800000
		m_MemSize = lngSize;
		if (strName.Length > 0) 
		{
			//创建内存共享体(INVALID_HANDLE_VALUE)
			m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);
			if (m_hSharedMemoryFile == IntPtr.Zero) 
			{
				m_bAlreadyExist = false;
				m_bInit = false;
				return 2;
				//创建共享体失败
			} else 
			{
				if (GetLastError() == ERROR_ALREADY_EXISTS)  //已经创建 
				{
					m_bAlreadyExist = true;
				} else                                         //新创建 
				{
					m_bAlreadyExist = false;
				}
			}
			//---------------------------------------
			//创建内存映射
			m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_WRITE, 0, 0, (uint)lngSize);
			if (m_pwData == IntPtr.Zero) 
			{
				m_bInit = false;
				CloseHandle(m_hSharedMemoryFile);
				return 3;
				//创建内存映射失败
			} else 
			{
				m_bInit = true;
				if (m_bAlreadyExist == false) 
				{
					//初始化
				}
			}
			//----------------------------------------
		} else 
		{
			return 1;
			//参数错误
		}
		return 0;
		//创建成功
	}
	/// <summary>
	/// 关闭共享内存
	/// </summary>
	public void Close() 
	{
		if (m_bInit) 
		{
			UnmapViewOfFile(m_pwData);
			CloseHandle(m_hSharedMemoryFile);
		}
	}
	/// <summary>
	/// 读数据
	/// </summary>
	/// <param name="bytData">数据</param>
	/// <param name="lngAddr">起始地址</param>
	/// <param name="lngSize">个数</param>
	/// <returns></returns>
	public int Read(ref byte[] bytData, int lngAddr, int lngSize) 
	{
		if (lngAddr + lngSize > m_MemSize) return 2;
		//超出数据区
		if (m_bInit) 
		{
			Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
		} else 
		{
			return 1;
			//共享内存未初始化
		}
		return 0;
		//读成功
	}
	/// <summary>
	/// 写数据
	/// </summary>
	/// <param name="bytData">数据</param>
	/// <param name="lngAddr">起始地址</param>
	/// <param name="lngSize">个数</param>
	/// <returns></returns>
	public int Write(byte[] bytData, int lngAddr, int lngSize) 
	{
		if (lngAddr + lngSize > m_MemSize) return 2;
		//超出数据区
		if (m_bInit) 
		{
			Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
		} else 
		{
			return 1;
			//共享内存未初始化
		}
		return 0;
		//写成功
	}
}

 

ShareMem MemDB = new ShareMem();//声明共享内存操作类
MemDB.Init("shared", 64* 1024 * 1024);//初始化共享内存   返回0表示初始化成功
byte[] bytes = new byte[2];
MemDB.Read(ref bytes, 0, 2);//读取数据,返回0表示读取成功
MemDB.Write(bytes, 0, 2);//写入数据

 

 

转载请注明:清风博客 » C#实现共享内存

喜欢 (1)or分享 (0)
支付宝扫码打赏 微信打赏
发表我的评论
取消评论

CAPTCHA Image
Reload Image
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址