首页 > 代码库 > 记录一下
记录一下
Date:2017-7-16
进程间通信的方式有很多,常用的方式有:
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 = http://www.mamicode.com/-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(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); //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 = http://www.mamicode.com/(byte*)src; while ((*pdst++ = *psrc++) != ‘\0‘) ; } } }}
记录一下
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。