1. 程式人生 > >記錄一下

記錄一下

定義 off 建立 ons pct 內存 efi art ber

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 = -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 = (byte*)src; while ((*pdst++ = *psrc++) != \0) ; } } } }

記錄一下