博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 进程间通信(共享内存)
阅读量:6671 次
发布时间:2019-06-25

本文共 6779 字,大约阅读时间需要 22 分钟。

原文:

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

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 = -
1;
        
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,  
//
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);
        
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(11"WriteMap");//开始的时候有一个可以写
            m_Read = new Semaphore(01"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, 000);
            //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[100];
                    byteCopy(byteStr, addr);
                    string str = Encoding.Default.GetString(byteStr, 0, 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 = -
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);
        
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 = 
1024;
            
        }
        
private 
void button1_Click(
object sender, EventArgs e)
        {
            
try
            {
                m_Write = Semaphore.OpenExisting(
"
WriteMap
");
                m_Read = Semaphore.OpenExisting(
"
ReadMap
");
                handle = OpenFileMapping(FILE_MAP_WRITE, 
0
"
shareMemory
");
                addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 
0
0
0);
                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 = 
0; i < byteSrc.Length; i++)
                {
                    *pDst = *psrc;
                    pDst++;
                    psrc++;
                }
            }
        }
   }
}

 

转载地址:http://ofmxo.baihongyu.com/

你可能感兴趣的文章
前端源码安全
查看>>
java二维数组的常见初始化
查看>>
关于开发WPF的一些感想
查看>>
UML介绍--用例图
查看>>
iOS 真机调试(史上最详细步骤解析,hmt精心打造)
查看>>
LVS三种模式与八种调度算法
查看>>
让定义的接口可读性更强
查看>>
WordPress上传含有中文文件出现乱码
查看>>
解析UIControl
查看>>
【MySQL】数据库字符校对规则
查看>>
分形几何算法和实现(C语言)
查看>>
设计模式[2]-Chain of Responsibility
查看>>
Nginx+Tomcat动静分离及Nginx优化(企业案例)
查看>>
软件事务内存导论(五)创建嵌套事务
查看>>
[翻译] ClockView 时钟
查看>>
Cocos2d-X-3.0之后的版本的环境搭建
查看>>
[翻译] TCBlobDownload
查看>>
阿里云DTS VS MySQLdump
查看>>
MonetDB 1.6 billion(384GB) JOIN 2.4 billion(576GB) 60 columns-random-data wide-table
查看>>
类型属性、方法
查看>>