亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

win32下進程間通信(共享內存)實例分析

2020-01-26 15:28:31
字體:
來源:轉載
供稿:網友

一、概述

很多情況下在Windows程序中,各個進程之間往往需要交換數據,進行數據通訊。WIN32 API提供了許多函數使我們能夠方便高效的進行進程間的通訊,通過這些函數我們可以控制不同進程間的數據交換。

進程間通訊(即:同機通訊)和數據交換有多種方式:消息、共享內存、匿名(命名)管道、郵槽、Windows套接字等多種技術?!肮蚕韮却妗保╯hared memory)可以定義為對一個以上的進程是可見的內存或存在于多個進程的虛擬地址空間。例如:如果兩個進程使用相同的DLL,只把DLL的代碼頁裝入內存一次,其他所有映射這個DLL的進程只要共享這些代碼頁就可以了;利用消息機制實現IPC雖然有交換的數據量小、攜帶的信息少等缺點,但由于其實現方便、應用靈活而廣泛應用于無須大量、頻繁數據交換的內部進程通訊系統之中。

二、同機進程間共享內存的實現

采用內存映射文件實現WIN32進程間的通訊:Windows中的內存映射文件的機制為我們高效地操作文件提供了一種途徑,它允許我們在WIN32進程中保留一段內存區域,把硬盤或頁文件上的目標文件映射到這段虛擬內存中。注意:在程序實現中必須考慮各進程之間的同步問題。

具體實現步驟如下:

1、在服務器端進程中調用內存映射API函數CreateFileMapping創建一個有名字標識的共享內存;

函數CreateFileMapping原型如下:

HANDLE CreateFileMapping (HANDLE hFile, // 映射文件的句柄,若設為0xFFFFFFFF(即:INVALID_HANDLE_VALUE)則創建一個進程間共享的對象LPSECURITY_ATTRIBUTES lpFileMappingAttributes, //安全屬性DWORD flProtect, //保護方式DWORD dwMaximumSizeHigh, //對象的大小DWORD dwMaximumSizeLow, LPCTSTR lpName // 映射文件名,即共享內存的名稱);

與虛擬內存類似,保護方式參數可以是PAGE_READONLY或是PAGE_READWRITE。如果多進程都對同一共享內存進行寫訪問,則必須保持相互間同步。映射文件還可以指定PAGE_WRITECOPY標志,可以保證其原始數據不會遭到破壞,同時允許其他進程在必要時自由的操作數據的拷貝。

例如:創建一個名為“zzj”的長度為4096字節的有名映射文件:

HANDLE m_hMapFile=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,0x1000," zzj");

2、在創建文件映射對象后,服務器端進程調用MapViewOfFile函數映射到本進程的地址空間內;
例:映射緩存區視圖

void* m_pBaseMapFile=MapViewOfFile(m_hMapFile,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);

3、客戶端進程訪問共享內存對象,需要通過內存對象名調用OpenFileMapping函數,以獲得共享內存對象的句柄

HANDLE m_hMapFile =OpenFileMapping(FILE_MAP_WRITE,FALSE," zzj"); 

4、如果客戶端進程獲得共享內存對象的句柄成功,則調用MapViewOfFile函數來映射對象視圖。用戶可以使用該對象視圖來進行數據讀寫操作,以達到數據通訊的目的。
例:映射緩存區視圖

void* m_pBaseMapFile=MapViewOfFile(m_hMapFile,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);

5、當用戶進程結束使用共享內存后,調用UnmapViewOfFile函數以取消其地址空間內的視圖:

if (m_pBaseMapFile) {   UnmapViewOfFile(m_pBaseMapFile);   SharedMapView=NULL; }

三、使用文件映射實現共享內存。

FileMapping用于將存在于磁盤的文件放進一個進程的虛擬地址空間,并在該進程的虛擬地址空間中產生一個區域用于“存放”該文件,這個空間就叫做File View(存放在進程的虛擬內存中),系統并同時產生一個File Mapping Object(存放于物理內存中)用于維持這種映射關系,這樣當多個進程需要讀寫那個文件的數據時,它們的File View其實對應的都是同一個File Mapping Object,這樣做可節省內存和保持數據的同步性,并達到數據共享的目的。

當然在一個應用向文件中寫入數據時,其它進程不應該去讀取這個正在寫入的數據。這就需要進行一些同步的操作。下邊來看一下具體的API。

CreateFileMaping的用法:

HANDLE CreateFileMapping( //返回FileMapping Object的句柄HANDLE hFile, //想要產生映射的文件的句柄LPSECURITY_ATTRIBUTES lpAttributes, //安全屬性(只對NT和2000生效)DWORD flProtect, //保護標致DWORD dwMaximumSizeHigh, //在DWORD的高位中存放File Mapping Object //的大小DWORD dwMaximumSizeLow, //在DWORD的低位中存放File Mapping Object //的大小(通常這兩個參數有一個為0)LPCTSTR lpName //File Mapping Object的名稱。);

1)物理文件句柄

任何可以獲得的物理文件句柄,如果你需要創建一個物理文件無關的內存映射也無妨,將它設置成為 0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.

如果需要和物理文件關聯,要確保你的物理文件創建的時候的訪問模式和"保護設置"匹配,比如:物理文件只讀,內存映射需要讀寫就會發生錯誤。推薦你的物理文件使用獨占方式創建。

如果使用 INVALID_HANDLE_VALUE,也需要設置需要申請的內存空間的大小,無論物理文件句柄參數是否有效,這樣 CreateFileMapping就可以創建一個和物理文件大小無關的內存空間給你,甚至超過實際文件大小,如果你的物理文件有效,而大小參數為0,則返回給你的是一個和物理文件大小一樣的內存空間地址范圍。返回給你的文件映射地址空間是可以通過復制,集成或者命名得到,初始內容為0。

2)保護設置

就是安全設置,不過一般設置NULL就可以了,使用默認的安全配置. 在win2k下如果需要進行限制,這是針對那些將內存文件映射共享給整個網絡上面的應用進程使用是,可以考慮進行限制.

3)高位文件大小

32位地址空間,設置為0。

4) 共享內存名稱

命名可以包含 "Global"或者 "Local" 前綴在全局或者會話名空間初級文件映射.其他部分可以包含任何除了()以外的字符,可以參考 Kernel Object Name Spaces.

5)調用CreateFileMapping的時候GetLastError的對應錯誤

ERROR_FILE_INVALID 如果企圖創建一個零長度的文件映射,應有此報
ERROR_INVALID_HANDLE 如果發現你的命名內存空間和現有的內存映射,互斥量,信號量,臨界區同名就麻煩了
ERROR_ALREADY_EXISTS 表示內存空間命名已經存在

使用函數CreateFileMapping創建一個想共享的文件數據句柄,然后使用MapViewOfFile來獲取共享的內存地址,然后使用OpenFileMapping函數在另一個進程里打開共享文件的名稱,這樣就可以實現不同的進程共享數據。

代碼示例:這個程序包括一個客戶端和一個服務端,服務端創建共享內存,客戶端打開共享內存,兩者通過兩個事件互斥訪問共享內存,實現一個小功能,就是服務端進程從控制臺讀入數據發送給客戶端進程。

服務端:

#include "stdafx.h" #include <Windows.h> #include <iostream> using namespace std;  int main() {   HANDLE hMutex      = NULL;   HANDLE hFileMapping   = NULL;   LPVOID lpShareMemory  = NULL;   HANDLE hServerWriteOver = NULL;   HANDLE hClientReadOver = NULL;    //create share memory   hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE,     NULL,     PAGE_READWRITE,     0,     1024*1024,     L"ShareMemoryTest");   if (NULL == hFileMapping)   {     cout << "CreateFileMapping fail:" << GetLastError() << endl;     goto SERVER_SHARE_MEMORY_END;   }    lpShareMemory = MapViewOfFile(hFileMapping,     FILE_MAP_ALL_ACCESS,     0,     0,   //memory start address     0);   //all memory space   if (NULL == lpShareMemory)   {     cout << "MapViewOfFile" << GetLastError() << endl;     goto SERVER_SHARE_MEMORY_END;   }    hMutex = CreateMutex(NULL, FALSE, L"SM_Mutex");   if (NULL == hMutex || ERROR_ALREADY_EXISTS == GetLastError())   {     cout << "CreateMutex" << GetLastError() << endl;     goto SERVER_SHARE_MEMORY_END;   }//多個線程互斥訪問    //send data   hServerWriteOver = CreateEvent(NULL,     TRUE,     FALSE,     L"ServerWriteOver");   hClientReadOver = CreateEvent(NULL,     TRUE,     FALSE,     L"ClientReadOver");   if (NULL == hServerWriteOver ||     NULL == hClientReadOver)   {     cout << "CreateEvent" << GetLastError() << endl;     goto SERVER_SHARE_MEMORY_END;   }    char p = 0;   char* q = (char*)lpShareMemory;   do    {     p = getchar();     if (WaitForSingleObject(hClientReadOver, 5*1000) != WAIT_OBJECT_0)        goto SERVER_SHARE_MEMORY_END;     q[0] = p;     if (!ResetEvent(hClientReadOver)) goto SERVER_SHARE_MEMORY_END;//把指定的事件對象設置為無信號狀態     if (!SetEvent(hServerWriteOver)) goto SERVER_SHARE_MEMORY_END;//把指定的事件對象設置為有信號狀態   } while (p != '/n');  SERVER_SHARE_MEMORY_END:   //release share memory   if (NULL != hServerWriteOver)  CloseHandle(hServerWriteOver);   if (NULL != hClientReadOver)  CloseHandle(hClientReadOver);   if (NULL != lpShareMemory)   UnmapViewOfFile(lpShareMemory);   if (NULL != hFileMapping)    CloseHandle(hFileMapping);   if (NULL != hMutex)       ReleaseMutex(hMutex);   return 0; } 

客戶端:

#include "stdafx.h" #include <Windows.h> #include <iostream> using namespace std; int main() {   HANDLE hMutex      = NULL;   HANDLE hFileMapping   = NULL;   LPVOID lpShareMemory  = NULL;   HANDLE hServerWriteOver = NULL;   HANDLE hClientReadOver = NULL;    hMutex = OpenMutex(MUTEX_ALL_ACCESS,     FALSE,     L"SM_Mutex");   if (NULL == hMutex)   {     if (ERROR_FILE_NOT_FOUND == GetLastError())     {       cout << "OpenMutex fail: file not found!" << endl;       goto CLIENT_SHARE_MEMORY_END;     }     else     {       cout << "OpenMutex fail:" << GetLastError() << endl;       goto CLIENT_SHARE_MEMORY_END;     }   }    if (WaitForSingleObject(hMutex, 5000) != WAIT_OBJECT_0)//hMutex 一旦互斥對象處于有信號狀態,則該函數返回   {     DWORD dwErr = GetLastError();     goto CLIENT_SHARE_MEMORY_END;   }    //open share memory   hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS,     FALSE,     L"ShareMemoryTest");   if (NULL == hFileMapping)   {     cout << "OpenFileMapping" << GetLastError() << endl;     goto CLIENT_SHARE_MEMORY_END;   }    lpShareMemory = MapViewOfFile(hFileMapping,     FILE_MAP_ALL_ACCESS,     0,     0,     0);   if (NULL == lpShareMemory)   {     cout << "MapViewOfFile" << GetLastError() << endl;     goto CLIENT_SHARE_MEMORY_END;   }    //read and write data   hServerWriteOver = CreateEvent(NULL,     TRUE,     FALSE,     L"ServerWriteOver");   hClientReadOver = CreateEvent(NULL,     TRUE,     FALSE,     L"ClientReadOver");   if (NULL == hServerWriteOver ||     NULL == hClientReadOver)   {     cout << "CreateEvent" << GetLastError() << endl;     goto CLIENT_SHARE_MEMORY_END;   }    char p = 0;   char* q = (char*)lpShareMemory;   do    {     if (!SetEvent(hClientReadOver))        goto CLIENT_SHARE_MEMORY_END;      if (WaitForSingleObject(hServerWriteOver, INFINITE) != WAIT_OBJECT_0)        goto CLIENT_SHARE_MEMORY_END;       p = q[0];     putchar(p);     if (!ResetEvent(hServerWriteOver))        goto CLIENT_SHARE_MEMORY_END;   } while (p != '/n');  CLIENT_SHARE_MEMORY_END:   //release share memory   if (NULL != hServerWriteOver)  CloseHandle(hServerWriteOver);   if (NULL != hClientReadOver)  CloseHandle(hClientReadOver);   if (NULL != lpShareMemory)   UnmapViewOfFile(lpShareMemory);   if (NULL != hFileMapping)    CloseHandle(hFileMapping);   if (NULL != hMutex)       ReleaseMutex(hMutex);   return 0; }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲护士老师的毛茸茸最新章节| 精品中文字幕在线观看| 国产精自产拍久久久久久蜜| 欧美日韩国产色| 久久激情五月丁香伊人| 国内精久久久久久久久久人| 亚洲人成网站免费播放| 狠狠色香婷婷久久亚洲精品| 国产91在线视频| 日韩一级裸体免费视频| 亚洲国产成人精品久久久国产成人一区| 国产成+人+综合+亚洲欧美丁香花| 欧美成人免费小视频| 亚洲第一网站免费视频| 富二代精品短视频| 亚洲欧洲视频在线| 91免费看视频.| 久久成人18免费网站| 国产91亚洲精品| 欧美日韩在线一区| 中国china体内裑精亚洲片| 日本不卡高字幕在线2019| 亚洲国产美女久久久久| 中文字幕精品av| 日韩精品高清视频| 国产成人精品久久二区二区91| 久久精品亚洲一区| 欧美午夜精品伦理| 九九热在线精品视频| 色综合久久天天综线观看| 国产日产欧美a一级在线| 久久久久久久久久久免费精品| 91精品国产综合久久久久久久久| 欧美午夜片在线免费观看| 91精品视频专区| 欧美夫妻性生活视频| 日本a级片电影一区二区| 国产成+人+综合+亚洲欧美丁香花| 影音先锋欧美在线资源| 欧美电影《睫毛膏》| 日韩a**中文字幕| 性欧美长视频免费观看不卡| 伊人青青综合网站| 国产精品激情av在线播放| 国产精品夜间视频香蕉| 欧美性开放视频| 91久久国产精品91久久性色| 成人一区二区电影| 亚洲人成免费电影| 亚洲精品国产拍免费91在线| 久久久久久av| 成人美女av在线直播| 久久精品精品电影网| 92版电视剧仙鹤神针在线观看| 亚洲在线第一页| 国产精品视频色| 久久精品亚洲94久久精品| 国产精品亚发布| 欧美日韩激情网| 欧美精品videosex性欧美| 亚洲美腿欧美激情另类| 日韩精品极品在线观看播放免费视频| 秋霞成人午夜鲁丝一区二区三区| 色琪琪综合男人的天堂aⅴ视频| 日韩激情视频在线播放| 精品magnet| 国产精品99久久久久久人| 日本不卡高字幕在线2019| 精品国产999| 欧美成人四级hd版| 欧美又大又粗又长| 91精品国产电影| 国产69精品99久久久久久宅男| 日韩电影大全免费观看2023年上| 国产精品18久久久久久首页狼| 中文字幕久热精品在线视频| 亚洲va欧美va国产综合久久| 欧美性高跟鞋xxxxhd| 久久精品美女视频网站| 97久久伊人激情网| 亚洲影视九九影院在线观看| 国产亚洲欧美另类中文| www国产精品视频| 久久99青青精品免费观看| 久久天天躁狠狠躁夜夜躁| 国产成人精品综合久久久| 中文字幕亚洲精品| 欧美黑人巨大xxx极品| 国产小视频国产精品| 欧美视频在线免费| 亚洲精品美女久久久久| 国产精品夜色7777狼人| 国产一区二区三区免费视频| 5252色成人免费视频| 中文国产成人精品久久一| 国自产精品手机在线观看视频| 国产精品777| 亚洲区一区二区| 中文综合在线观看| 色综合天天狠天天透天天伊人| 亚洲欧美日韩高清| 久久精品国产精品亚洲| 亚洲免费一在线| 亚洲色图欧美制服丝袜另类第一页| 97视频在线观看播放| 久久久久久久国产精品视频| 亚洲国产精品va在线看黑人动漫| 在线观看不卡av| 亚洲激情自拍图| 亚洲加勒比久久88色综合| 中文字幕精品影院| 成人国产精品免费视频| 国产91色在线播放| 久久久国产在线视频| 日韩福利在线播放| 日韩电影免费观看中文字幕| 久久综合久中文字幕青草| 欧美日韩福利视频| 日韩中文字幕国产| 国产成人综合一区二区三区| 丰满岳妇乱一区二区三区| 欧美一级大片在线免费观看| 欧美裸体xxxxx| 国产精品91免费在线| 亚洲精品白浆高清久久久久久| 欧美日韩免费在线观看| 亚洲天堂成人在线| 色婷婷av一区二区三区久久| 一本久久综合亚洲鲁鲁| 97成人精品区在线播放| 一区二区av在线| 欧美疯狂做受xxxx高潮| 亚洲第一区在线| 亚洲国产成人精品久久久国产成人一区| 久久人人爽人人爽人人片av高清| 高清欧美电影在线| 热草久综合在线| 欧美极品美女电影一区| 精品久久久久久久久久久| 欧美成人免费全部观看天天性色| 久久国产精品网站| 中日韩午夜理伦电影免费| 欧美成人免费一级人片100| 日韩av在线免费看| 亚洲天堂免费在线| 国产精品视频白浆免费视频| 久久久精品免费| 中文字幕av一区二区三区谷原希美| 欧美最猛黑人xxxx黑人猛叫黄| 性欧美xxxx交| 欧美精品在线播放| 欧美性xxxxhd| 国产97在线视频| 成人性生交xxxxx网站| 九九热99久久久国产盗摄| 亚洲人成网站免费播放| 精品久久久久久久久久久久久久| 亚洲在线视频观看| 精品久久久91| 欧美日韩人人澡狠狠躁视频| 国产亚洲欧洲高清| 亚洲精品国偷自产在线99热| 狠狠做深爱婷婷久久综合一区| 精品国产乱码久久久久久天美|