社区
进程/线程/DLL
帖子详情
求进程间通信-共享内存的例子
sunnycrystal_2008
2008-05-25 09:59:40
最近正在学习进程间通信,知道有很多种实现方法,我想求一个简单的共享内存通信的例子,谢谢了!!
...全文
4223
8
打赏
收藏
求进程间通信-共享内存的例子
最近正在学习进程间通信,知道有很多种实现方法,我想求一个简单的共享内存通信的例子,谢谢了!!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
8 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
lvbing2046
2010-12-02
打赏
举报
回复
看看先。
gz_runwe
2010-06-11
打赏
举报
回复
很好,我试一下先
liuxingbin
2009-08-18
打赏
举报
回复
挺好的,讲的也很详细
bc05008
2008-07-30
打赏
举报
回复
谢谢楼主的奉献,最近正在学进程间通信的知识~!!!!
masterz
2008-05-27
打赏
举报
回复
推荐使用boost::interprocess::shared_memory_object
http://www.boost.org/doc/libs/1_35_0/doc/html/interprocess/sharedmemorybetweenprocesses.html
Windows下使用boost::interprocess::windows_shared_memory速度更快一些。
sunnycrystal_2008
2008-05-25
打赏
举报
回复
三楼的文章还没发完吧,下面的内容能继续发吗?
zyyoung
2008-05-25
打赏
举报
回复
一、 引言
在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换.
内部进程间通讯(即:同机通讯)和数据交换有多种方式:消息、共享内存、匿名(命名)管道、邮槽、Windows套接字等多种技术。“共享内存”(shared memory)可以定义为对一个以上的进程是可见的内存或存在于多个进程的虚拟地址空间。例如:如果两个进程使用相同的DLL,只把DLL的代码页装入内存一次,其他所有映射这个DLL的进程只要共享这些代码页就可以了;利用消息机制实现IPC虽然有交换的数据量小、携带的信息少等缺点,但由于其实现方便、应用灵活而广泛应用于无须大量、频繁数据交换的内部进程通讯系统之中。本文通过共享内存实现进程间的数据交换,利用windows消息机制实现进程间的同步,两种机制结合使用,不仅解决了交换数据量小的问题,还解决了进程并发存取数据的问题。
二、 同机进程间共享内存的实现
采用内存映射文件实现WIN32进程间的通讯:Windows中的内存映射文件的机制为我们高效地操作文件提供了一种途径,它允许我们在WIN32进程中保留一段内存区域,把目标文件映射到这段虚拟内存中。在程序实现中必须考虑各进程之间的同步问题。具体实现步骤如下:
1、在服务器端进程中调用内存映射API函数CreateFileMapping创建一个有名字标识的共享内存;
函数CreateFileMapping原型
HANDLE CreateFileMapping (
HANDLE hFile, // 映射文件的句柄,若设为0xFFFFFFFF则创建一个进程间共享的对象
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;
}
三、 利用消息实现内部进程通讯
1、Windows消息机制简介
Windows是一种面向对象的体系结构,Windows环境和应用程序都是通过消息来交互的。Windows应用程序开始执行后,Windows为该程序创建一个"消息队列(message queue)",用以存放邮寄给该程序可能创建的各种不同窗口的消息。消息队列中消息的结构(MSG)为:
typedef struct tagMSG{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
}MSG;
其中第一个成员变量是用以标识接收消息的窗口的窗口句柄;第二个参数便是消息标识号,如WM_PAINT;第三个和第四个参数的具体意义和message值有关,均为消息参数。前四个参数是非常重要和经常用到的,至于后两个参数则分别表示邮寄消息的时间和光标位置(屏幕坐标)。
把消息传送到应用程序有两种方法:一种是由系统将消息"邮寄(post)"到应用程序的"消息队列",这是"进队消息",Win32 API有对应的函数:PostMessage(),此函数不等待该消息处理完就返回;而另一种则是由系统在直接调用窗口函数时将消息"发送(send)"给应用程序的窗口函数,属于"不进队消息",对应的函数是SendMessage(),该函数必须等待消息处理完后方可返回。
2、同机进程利用Windows自定义消息进行通信的方法:
◆ 在发送方程序和接收方程序中均定义Windows自定义消息:
例如:#define WM_SERVERDATACHANGE WM_USER+999
◆ 获取接收方的接收消息的窗口对象
(1)通过接收方程序的窗口标题获取接收方程序的窗口对象,调用函数为:
static CWnd* PASCAL FindWindow(
LPCTSTR lpszClassName, //窗口类名称,可为NULL
LPCTSTR lpszWindowName ); //窗口标题
例如:接收方程序的窗口标题为“WFClient”
CString str="WFClient";
CWnd *pWnd=CWnd::FindWindow(NULL,str);
(2)通过窗口句柄获取接收方程序的窗口对象,调用函数为:
static CWnd* PASCAL FromHandle( HWND hWnd );
◆ 获取接收方程序的窗口对象后,调用窗口类的SendMessage()或PostMessage()函数
发送消息
BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
LRESULT SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
例:if(pWnd)
pWnd->PostMessage(WM_ SERVERDATACHANGE ,0,0);
◆ 在接收方程序中响应自定义消息,须放在主框架类中,否则不响应
void CMainFrame::OnData2Chane(WPARAM wParam, LPARAM lParam)
{
AfxMessageBox("receive WM_USER+999");
}
四、 实例程序
1、设计概述
◆ 本实例采用WINDOWS系统共享内存方式,在同一结点上运行的服务器端程序与客户端程序进行数据交换,共享内存的名称为“zzj”
◆ 共享内存分为不同的数据区,服务器端程序与客户端程序刷新各自的数据区,同时访问对方的数据区以获得实时的数据,数据区定义如下:
(1) 数据区1(客户端修改,服务器端读取):
数据区长度为 4*(n+1) bytes, n 为数据个数(每个数据对应一个点),其结构如下所示:
数据个数+1 (INT ,4BYTES)
数据1 (INT ,4BYTES)
数据2 (INT ,4BYTES)
、、、、、
数据N (INT ,4BYTES)
(2) 数据区2(服务端修改,客户端读取):
数据区长度为 4*(n+1) bytes, n 为数据个数(每个数据对应一个点),其结构如下所示:
数据个数 (INT ,4BYTES)
数据1 (INT ,4BYTES)
数据2 (INT ,4BYTES)
、、、、、
数据N (INT ,4BYTES)
(3) 窗口句柄区
窗口句柄区长度为8 bytes,服务器端和客户端使用对方的窗口句柄传递WINDOWS用户自定义消息,其结构如下图所示:
服务器端窗口句柄(4bytes)
客户端窗口句柄 (4bytes)
◆ 由于对共享内存数据访问存在并发性,服务器端程序与客户端程序使用对方的窗口句柄传递WINDOWS用户自定义消息来实现相互数据转送的驱动。一般情况下,当服务器端程序的数据区2发生变化时应主动向客户端程序发消息;客户端更改数据区1后,也应主动向服务端发送消息,通知服务端读取。
◆ 用户自定义WINDOWS消息
(1)、服务端 à 客户端
#define WM_SERVERDATACHANGE WM_USER+999
当服务端发现数据区2发生变化时,发出此消息
(2)、客户端 à 服务端
#define WM_CLIENTDATACNANGE WM_USER+998
当客户端发现数据区1发生变化时,发出此消息
2、实现过程
(1) 利用VC++6.0 的AppWizard分别创建二个单文档SDI应用程序,项目名分别为“WFServer”、“WFClient”,视图类的基类采用CFormView。
(2) 为了便于扩展与应用,笔者在两个进程中封装了对应的两个类CServerData和CClientData 你可以根据自己的共享内存区协议,在这两个类的基础上添加新的功能。CServerData类是服务器端的封装类,主要功能:创建共享内存区,建立映射缓存区视图,初始化共享内存区的各数据区指针,读、写相应数据区的数据,类的定义如下:
八卦之魂
2008-05-25
打赏
举报
回复
http://blog.csdn.net/firebird321/archive/2007/09/05/1774011.aspx
Windows
进程间通信
-
共享内存
做项目时要用到进程间的通信,把服务程序和普通界面程序建立通信,记录一下用到的方法防止忘记 首先这里用的是
共享内存
的通信方式
共享内存
的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间上,这样每个进程都可以读取同一份数据,从而实现进程通信。因为是通过内存操作实现通信,因此是一种最高效的数据交换方法。
共享内存
在 Windows 中是用 FileMapping 实现的,从具体的
Linux
进程间通信
--
共享内存
示例(信号量保证同步)
在Linux系统中,每个进程都有独立的虚拟内存空间,也就是说不同的进程访问同一段虚拟内存地址所得到的数据是不一样的,这是因为不同进程相同的虚拟内存地址会映射到不同的物理内存地址上。\n但有时候为了让不同进程之间进行通信,需要让不同进程共享相同的物理内存,Linux通过
共享内存
来实现这个功能。下面先来介绍一下Linux系统的
共享内存
的使用。 ...
Linux
进程间通信
——使用
共享内存
下面将讲解
进程间通信
的另一种方式,使用
共享内存
。 一、什么是
共享内存
顾名思义,
共享内存
就是允许两个不相关的进程访问同一个逻辑内存。
共享内存
是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段
共享内存
连接到它们自己的地址空间中,所有进程都可以访问
共享内存
中的地址,就好像它们是由用C语言函数malloc分配的内存一
Linux
进程间通信
-
共享内存
前言本文主要说明在Linux环境上如何使用
共享内存
。阅读本文可以帮你解决以下问题: 什么是
共享内存
和为什么要有
共享内存
? 如何使用mmap进行
共享内存
? 如何使用XSI
共享内存
? 如何使用POSIX
共享内存
? 如何使用hugepage
共享内存
以及
共享内存
的相关限制如何配置?
共享内存
都是如何实现的? 使用文件或管道进行
进程间通信
会有很多局限性,比如效率问题以及数据处理使用文件描述符而不如内存
Qt实现IPC
进程间通信
-
共享内存
方式
QT封装了QSharedMemory类实现
共享内存
,可以共享文本、图片等各种数据格式,支持windows和linux跨平台使用;示例代码新建两个工程,分别启动两个应用程序,实现文本数据的共享。
进程/线程/DLL
15,466
社区成员
49,169
社区内容
发帖
与我相关
我的任务
进程/线程/DLL
VC/MFC 进程/线程/DLL
复制链接
扫一扫
分享
社区描述
VC/MFC 进程/线程/DLL
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章