C#共享内存类改进版
原文 C#共享内存类改进版
改进说明及源码实例下载见:http://blog.csdn.net/zzh8845/archive/2008/11/22/3349963.aspx
ShareMem.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
namespace ShareMemLib
{
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;
IntPtr m_pwDataWrite = IntPtr.Zero;
IntPtr m_pwDataRead = IntPtr.Zero;
bool m_bAlreadyExist = false;
bool m_bInit = false;
long m_MemSize = 0;
int m_length = 0;
int m_count = 0;
const int infoSize = 50;
Semaphore semRead;
Semaphore semWrite;
Semaphore semWriteLength;
String m_pathMSGCSV = "Messages.csv";
public ShareMem()
{
}
~ShareMem()
{
Close();
}
///
/// 初始化共享内存
///
/// 共享内存名称
/// 共享内存大小
///
public int Init(string strName, long lngSize)
{
if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 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 (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
{
m_bAlreadyExist = true;
m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, 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_ALL_ACCESS, 0, 0, (uint)lngSize);
m_pwDataWrite = m_pwData;
m_pwDataRead = (IntPtr)(m_pwData.GetHashCode() + infoSize);
if (m_pwData == IntPtr.Zero)
{
m_bInit = false;
CloseHandle(m_hSharedMemoryFile);
return 3; //创建内存映射失败
}
else
{
m_bInit = true;
if (m_bAlreadyExist == false)
{
//初始化
}
}
//----------------------------------------
}
else
{
return 1; //参数错误
}
SetSemaphore();
if (m_bAlreadyExist == false)
{
WriteLengthAndCount(0, 0);
}
return 0; //创建成功
}
///
/// 关闭共享内存
///
public void Close()
{
if (m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}
public bool SetSemaphore()
{
try
{
semRead = Semaphore.OpenExisting("ReadShareMemory");
semWrite = Semaphore.OpenExisting("WriteShareMemory");
semWriteLength = Semaphore.OpenExisting("WriteLengthShareMemory");
}
catch (Exception)
{
semRead = new Semaphore(0, 1, "ReadShareMemory");
semWrite = new Semaphore(1, 1, "WriteShareMemory");
semWriteLength = new Semaphore(1, 1, "WriteLengthShareMemory");
}
return true;
}
/**
public int ReadLength()
{
Byte[] bytData = new Byte[infoSize];
if (infoSize > m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Marshal.Copy(m_pwData, bytData, 0, infoSize);
}
else
{
return 1; //共享内存未初始化
}
String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0');
m_length = System.Convert.ToInt32(str);
return 0; //读成功
}
public int WriteLength(int length)
{
semWriteLength.WaitOne();
if (infoSize > m_MemSize) return 2; //超出数据区
String strLength = System.Convert.ToString(length);
Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLength);
if (m_bInit)
{
Marshal.Copy(bytData, 0, m_pwData, bytData.Length);
}
else
{
semWriteLength.Release();
return 1; //共享内存未初始化
}
semWriteLength.Release();
return 0;
}
**/
public int ReadLengthAndCount()
{
Byte[] bytData = new Byte[infoSize];
if (infoSize > m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Marshal.Copy(m_pwData, bytData, 0, infoSize);
}
else
{
return 1; //共享内存未初始化
}
String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0');
String[] strs = System.Text.RegularExpressions.Regex.Split(str, "/0");
m_length = System.Convert.ToInt32(strs[0]);
m_count = System.Convert.ToInt32(strs[1]);
return 0; //读成功
}
public int WriteLengthAndCount(int length, int count)
{
semWriteLength.WaitOne();
if (infoSize > m_MemSize) return 2; //超出数据区
String strLengthAndCount = System.Convert.ToString(length) + "/0" + System.Convert.ToString(count);
Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLengthAndCount);
if (m_bInit)
{
/**
Byte[] byteZero = new Byte[infoSize];
for (int i = 0; i < infoSize; i++)
{
byteZero[i] = (Byte)'/0';
}
Marshal.Copy(byteZero, 0, m_pwData, infoSize);
* **/
Marshal.Copy(bytData, 0, m_pwData, bytData.Length);
}
else
{
semWriteLength.Release();
return 1; //共享内存未初始化
}
semWriteLength.Release();
return 0;
}
///
/// 读数据
///
/// 数据
/// 起始地址
/// 个数
///
public int Read(ref byte[] bytData)
{
ReadLengthAndCount();
if (m_length > m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Marshal.Copy(m_pwDataRead, bytData, 0, m_length);
}
else
{
return 1; //共享内存未初始化
}
return 0; //读成功
}
///
/// 写数据
///
/// 数据
/// 起始地址
/// 个数
///
public int Write(byte[] bytData, int lngSize)
{
semWrite.WaitOne();
ReadLengthAndCount();
if (m_length + lngSize > m_MemSize)
{
System.Windows.Forms.MessageBox.Show("Share memory is full. " + (m_length + lngSize) + ">" + m_MemSize);
semWrite.Release();
return 2; //超出数据区
}
if (m_bInit)
{
m_pwDataWrite = (IntPtr)(m_pwData.GetHashCode() + m_length + infoSize);
Marshal.Copy(bytData, 0, m_pwDataWrite, lngSize);
m_length += lngSize;
m_count++;
}
else
{
semWrite.Release();
return 1; //共享内存未初始化
}
WriteLengthAndCount(m_length, m_count);
semWrite.Release();
return 0; //写成功
}
public int GetLength()
{
ReadLengthAndCount();
return this.m_length;
}
public int GetCount()
{
ReadLengthAndCount();
return this.m_count;
}
public int ReadCSV()
{
try
{
if (!File.Exists(m_pathMSGCSV))
File.CreateText(m_pathMSGCSV).Close();
StreamReader sr = System.IO.File.OpenText(m_pathMSGCSV);
while (!sr.EndOfStream)
{
String strLine = sr.ReadLine();
if (!System.String.IsNullOrEmpty(strLine))
{
strLine += "/0";
Byte[] data = System.Text.Encoding.Unicode.GetBytes(strLine);
Write(data, data.Length);
}
}
sr.Close();
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show("Error:ReadCSV()" + e);
return 1;
}
return 0;
}
public int WriteCSV()
{
try
{
StreamWriter sw = System.IO.File.AppendText(m_pathMSGCSV);
ReadLengthAndCount();
Byte[] btydata = new Byte[m_length];
Read(ref btydata);
String strOut = System.Text.Encoding.Unicode.GetString(btydata).Trim('/0');
String[] sArray = System.Text.RegularExpressions.Regex.Split(strOut, "/0");
foreach (String str in sArray)
{
if (!String.IsNullOrEmpty(str))
sw.WriteLine(str);
}
sw.Flush();
sw.Close();
}
catch (Exception)
{
System.Windows.Forms.MessageBox.Show("Error:WriteCSV()");
return 1;
}
return 0;
}
public int Clear()
{
ReadLengthAndCount();
if (infoSize + m_length > m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Byte[] byteZero = new Byte[infoSize + m_length];
for (int i = 0; i < infoSize; i++)
{
byteZero[i] = (Byte)'/0';
}
Marshal.Copy(byteZero, 0, m_pwData, infoSize + m_length);
m_pwDataWrite = m_pwData;
m_length = 0;
m_count = 0;
WriteLengthAndCount(0, 0);
}
return 0;
}
}
}
Form1.cs
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 ShareMemLib;
namespace ShareMemory
{
public partial class frmMain : Form
{
ShareMem MemDB = new ShareMem();
const int m_memSize = 4096000;
public frmMain()
{
InitializeComponent();
btnInit.Enabled = true;
btnWrite.Enabled = false;
btnRead.Enabled = false;
txtInput.Text = "AAA";
}
private void ReadTest()
{
String str = ReadToStr();
String[] strArray = System.Text.RegularExpressions.Regex.Split(str, "/0");
lstData.Items.Clear();
foreach (String s in strArray)
{
lstData.Items.Add(s);
}
}
private String ReadToStr()
{
int currentLength = MemDB.GetLength();
int currentCount = MemDB.GetCount();
Byte[] data = new Byte[currentLength];
MemDB.Read(ref data);
lblUsedSize.Text = currentLength.ToString();
lblCount.Text = currentCount.ToString();
return System.Text.Encoding.Unicode.GetString(data);
}
private void WriteStr(String str)
{
btnWrite.Enabled = false;
try
{
Byte[] data = System.Text.Encoding.Unicode.GetBytes(str);
MemDB.Write(data, data.Length);
}
catch (Exception)
{
MessageBox.Show("Error in WriteStr");
}
btnWrite.Enabled = true;
}
private void btnInit_Click(object sender, EventArgs e)
{
if (MemDB.Init("YFMemTest", m_memSize) != 0)
{
//初始化失败
MessageBox.Show("初始化失败");
}
else
{
btnInit.Enabled = false;
btnWrite.Enabled = true;
btnRead.Enabled = true;
}
lblTotalSize.Text = m_memSize.ToString();
}
private void btnClear_Click(object sender, EventArgs e)
{
MemDB.Clear();
ReadTest();
}
private void btnReadCSV_Click(object sender, EventArgs e)
{
MemDB.ReadCSV();
ReadTest();
}
private void btnWriteCSV_Click(object sender, EventArgs e)
{
MemDB.WriteCSV();
MemDB.Clear();
ReadTest();
}
private void btnRead_Click(object sender, EventArgs e)
{
ReadTest();
}
private void btnWrite_Click(object sender, EventArgs e)
{
//String str = "B000" + (i++) + ",1,1,2008,success/0";
String str = txtInput.Text + System.DateTime.Now.ToString(",yyyMMdd,HHmmss,fff/0");
WriteStr(str);
ReadTest();
}
}
}
C#共享内存类改进版的更多相关文章
- C#共享内存实例 附源码
原文 C#共享内存实例 附源码 网上有C#共享内存类,不过功能太简单了,并且写内存每次都从开头写.故对此进行了改进,并做了个小例子,供需要的人参考. 主要改进点: 通过利用共享内存的一部分空间(以下称 ...
- Boost:shared_memory_object --- 共享内存
什么是共享内存 共享内存是最快速的进程间通信机制.操作系统在几个进程的地址空间上映射一段内存,然后这几个进程可以在不需要调用操作系统函数的情况下在那段内存上进行读/写操作.但是,在进程读写共享内存时, ...
- 共享内存操作类(C#源码)
原文 http://blog.csdn.net/yefanqiu/article/details/1717458 VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由 ...
- PHP共享内存yac操作类
http://www.laruence.com/2013/03/18/2846.html 鸟哥介绍 https://www.cnblogs.com/willamwang/p/8918377.htm ...
- php操作共享内存shmop类及简单使用测试(代码)
SimpleSHM 是一个较小的抽象层,用于使用 PHP 操作共享内存,支持以一种面向对象的方式轻松操作内存段.在编写使用共享内存进行存储的小型应用程序时,这个库可帮助创建非常简洁的代码.可以使用 3 ...
- 撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)
一:任务描写叙述 A,B两个进程通过管道通信,像曾经的互相聊天一样,然后A进程每次接收到的数据通过A1进程显示(一个新进程,用于显示A接收到的信息),A和A1间的数据传递採用共享内存,相应的有一个B1 ...
- OpenMP共享内存并行编程详解
实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...
- java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...
- Linux IPC POSIX 共享内存
模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...
随机推荐
- Javascript知识四(DOM)
[箴 10:4] 手懒的,要受贫穷:手勤的,却要富足. He becometh poor that dealeth with a slack hand: but the hand of the di ...
- VS2010断点无效
可能的原因如下: 1. 菜单tools->Options->Debugging->General,有个Require source files to exactly match t ...
- 堆分配与栈分配---SAP C++电面(5)/FEI
一直以来总是对这个问题的认识比较朦胧,我相信很多朋友也是这样的,总是听到内存一会在栈上分配,一会又在堆上分配,那么它们之间到底是怎么的区别呢?为了说明这个问题,我们先来看一下内存内部的组织情况. 从上 ...
- 网络子系统48_ip协议数据帧的发送
//ip协议与l4协议接口,l4通过此接口向下l3传递数据帧 //函数主要任务: // 1.通过路由子系统路由封包 // 2.填充l3报头 // 3.ip分片 // 4.计算校验和 // 5.衔接邻居 ...
- hdu 1823 Luck and Love 二维线段树
题目链接 很裸的题, 唯一需要注意的就是询问时给出的区间并不是l<r, 需要判断然后交换一下, WA了好多发... #include<bits/stdc++.h> using nam ...
- Python中的isinstance函数
isinstance是Python中的一个内建函数 语法: isinstance(object, classinfo) 如果参数object是classinfo的实例,或者object是class ...
- SQL 设计心得、逗号分隔列表
第一: 在开始编码前.主要关注数据库里要保存什么样的数据,以级最佳的数据组织方式和内在关联方式. 第二: 使用你所知的数据库特性尽可能高效的实现数据管理.如正确的索引.数据库类型.高效的select! ...
- QCombobox设置下拉框的宽度
这几天写一个项目,里面用到qcombobox组件,其中下拉框含有129个子项,所以在点击的时候,一个下拉框就将整个电脑屏幕给占满了,很不好看并且在使用中会造成很大的苦恼.其实我就是想设置一个下拉框最大 ...
- MyBatis使用DEMO及cache的使用心得
下面是一个简单的MyBatis使用DEMO. 整体结构 整体代码大致如下: POM依赖 需要引用两个jar包,一个是mybatis,另一个是mysql-connector-java,如果是maven工 ...
- 教你看懂C++类库函数定义之三---_stdcall
一切从一个C++ 类库头文件开始,现在在做一个C++的项目,期间用到一个开源的界面库DUILib(类似MFC),这个东西还不错能很容易的写出漂亮的界面,比如QQ的界面,可以去下载下来研究研究,地址:h ...