zoukankan      html  css  js  c++  java
  • 记录一下

    Date:2018-7-26

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

    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++) != '')
                        ;
                }
    
            }
    
        }
    }
  • 相关阅读:
    原型设计作业
    案例分析作业
    编程作业
    阅读任务
    自我介绍
    5 20210420-1 团队作业1—团队展示
    3 20210405-1 案例分析作业
    阅读任务
    自我介绍
    原型设计
  • 原文地址:https://www.cnblogs.com/gyxdbk/p/7190363.html
Copyright © 2011-2022 走看看