当前位置:   article > 正文

Windows进程间通信 - 使用共享文件与内存_windows内存文件映射 进程间通信

windows内存文件映射 进程间通信

一、共享内存原理

在32位的系统中,每一个进程都有4G“连续”虚拟内存,且每一个进程这4G的虚拟内存块是互不共享。而为达到每个进程能够操作同一块内存,Window提供了内存映射文件的方式,简单的说每一个进程的一段虚拟内存对应于同一个文件或类文件的资源,使得每个进程能够操作同一个文件或类文件资源,从而达到内存共享的效果。

(1)为什么是4G?

32位系统寻址 2^32 = 4G

(2)连续的虚拟内存

虚拟内存计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

                                                                     

(3)文件映射

内存映射文件(Memory-mapped file),或称“文件映射”、“映射文件”,是一段虚内存逐字节对应于一个文件或类文件的资源,使得应用程序处理映射部分如同访问主内存

特别提醒:因为共享内存并没有提供同步机制,所以每个线程在访问临界区资源(共享内存)时,会相互影响,比如,一个进程正在写入,另一个进程同时也在写入,导致写入的数据错乱。所以为了解决这个,可以用到同步对象--Event。

二、一个小Demo

(1)Server流程:

1.创建共享文件

2.文件映射

3.获取映射首地址

4.读写数据

5.关闭文件句柄,卸载文件映射,关闭文件映射句柄

  1. // ProcessA.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //
  3. #include <Windows.h>
  4. #include <iostream>
  5. using namespace std;
  6. #define BUFFER_SIZE 256
  7. #define FILE_MAPPING_NAME L"FILE_MAPPING_NAME"
  8. #define EVENT_NAME1 L"EVNET_NAME1"
  9. #define EVENT_NAME2 L"EVNET_NAME2"
  10. int main()
  11. {
  12. HANDLE hFile = NULL;
  13. HANDLE hMap = NULL;
  14. char szBufIn[BUFFER_SIZE] = { 0 };
  15. char szBufOut[BUFFER_SIZE] = { 0 };
  16. LPTSTR pBeginAddress = NULL;
  17. //创建共享的文件
  18. hFile = CreateFile(
  19. L"一个路径",
  20. GENERIC_READ | GENERIC_WRITE,
  21. FILE_SHARE_READ | FILE_SHARE_WRITE,
  22. NULL,
  23. OPEN_ALWAYS,
  24. FILE_FLAG_SEQUENTIAL_SCAN,
  25. NULL
  26. );
  27. if (NULL == hFile)
  28. {
  29. cout << "CreateFile failed!" << endl;
  30. return 0;
  31. }
  32. //创建文件映射
  33. hMap = CreateFileMapping(
  34. hFile,
  35. NULL,
  36. PAGE_READWRITE,
  37. 0,
  38. BUFFER_SIZE,
  39. FILE_MAPPING_NAME
  40. );
  41. if (!hMap)
  42. {
  43. cout << "CreateFileMapping Failed!" << endl;
  44. return 0;
  45. }
  46. //获取映射首地址
  47. pBeginAddress = (LPTSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE);
  48. if (!pBeginAddress)
  49. {
  50. cout << "MapViewOfFile failed!" << endl;
  51. return 0;
  52. }
  53. HANDLE hEvent1 = CreateEvent(NULL, TRUE, TRUE, EVENT_NAME1);
  54. HANDLE hEvent2 = CreateEvent(NULL, TRUE, FALSE, EVENT_NAME2);
  55. while (true)
  56. {
  57. ZeroMemory(szBufIn, BUFFER_SIZE);
  58. ZeroMemory(szBufOut, BUFFER_SIZE);
  59. WaitForSingleObject(hEvent1, INFINITE);
  60. memcpy(szBufOut, pBeginAddress, BUFFER_SIZE);
  61. cout << "Shared Memory:" << szBufOut << endl;
  62. cout << "Pls:";
  63. cin.getline(szBufIn, BUFFER_SIZE);
  64. memcpy(pBeginAddress, szBufIn, BUFFER_SIZE);
  65. ResetEvent(hEvent1);
  66. SetEvent(hEvent2);
  67. }
  68. CloseHandle(hEvent1);
  69. CloseHandle(hEvent2);
  70. CloseHandle(hFile);
  71. UnmapViewOfFile(hMap);
  72. CloseHandle(hMap);
  73. }

(2)Client流程

1.打开文件映射

2.获取映射首地址

3.读写数据

4.关闭文件句柄,卸载文件映射,关闭文件映射句柄

  1. // ProcessB.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //
  3. #include <Windows.h>
  4. #include <iostream>
  5. using namespace std;
  6. #define BUFFER_SIZE 256
  7. #define FILE_MAPPING_NAME L"FILE_MAPPING_NAME"
  8. #define EVENT_NAME1 L"EVNET_NAME1"
  9. #define EVENT_NAME2 L"EVNET_NAME2"
  10. int main()
  11. {
  12. HANDLE hFile = NULL;
  13. HANDLE hMap = NULL;
  14. char szBufIn[BUFFER_SIZE] = { 0 };
  15. char szBufOut[BUFFER_SIZE] = { 0 };
  16. LPTSTR pBeginAddress = NULL;
  17. //打开文件映射
  18. hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,FILE_MAPPING_NAME);
  19. if (!hMap)
  20. {
  21. cout << "OpenFileMapping Failed!" << endl;
  22. return 0;
  23. }
  24. //获取映射首地址
  25. pBeginAddress = (LPTSTR)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE);
  26. if (!pBeginAddress)
  27. {
  28. cout << "MapViewOfFile failed!" << endl;
  29. return 0;
  30. }
  31. HANDLE hEvent1 = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME1);
  32. HANDLE hEvent2 = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME2);
  33. while (true)
  34. {
  35. ZeroMemory(szBufIn, BUFFER_SIZE);
  36. ZeroMemory(szBufOut, BUFFER_SIZE);
  37. WaitForSingleObject(hEvent2, INFINITE);
  38. memcpy(szBufOut, pBeginAddress, BUFFER_SIZE);
  39. cout << "Shared Memory:" << szBufOut << endl;
  40. cout << "Pls:";
  41. cin.getline(szBufIn, BUFFER_SIZE);
  42. memcpy(pBeginAddress, szBufIn, BUFFER_SIZE);
  43. ResetEvent(hEvent2);
  44. SetEvent(hEvent1);
  45. }
  46. CloseHandle(hEvent1);
  47. CloseHandle(hEvent2);
  48. CloseHandle(hFile);
  49. UnmapViewOfFile(hMap);
  50. CloseHandle(hMap);
  51. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/888882
推荐阅读
相关标签
  

闽ICP备14008679号