96SEO 2026-02-23 11:43 11
某些应用程序中进程/进程和线程/线程之间不可避免的进行通信进行消息传递数据共享等

同一进程的线程之间通信方式包括Windows中常用Event,
WM_COPYDATA消息以及ClipBoard(剪贴板)DDE,
在Tron系统中除了支持Event之外还支持MailBox,MessageBuffer等通讯手段
事件除了用来保证两个线程之间同步之外借由通知功能也可以作为线程之间的简单通信的手段
线程使用WaitForSingleObject等待一件事情的发生该事情可以由另外一个线程通过SetEvent进行触发。
使用WaitForMultipleObjects等待多个由其他线程触发的事件某些情况下在线程的函数中也给自己发送消息
将事件对象置为有信号状态然后立即置为无信号状态在实际开发中这个函数很少使用
不同进程之间也可以通过Event通知事件这可以通过命名对象来实现CreateEvent时指定了名称不同进程之间通过创建同名的Event就可以获得指向同一个内核对象的句柄这样不同进程间就可以互相通知和等待Event
Windows是一个消息Message驱动系统。
Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。
应用程序想要实现的功能由消息来触发并且靠对消息的响应和处理来完成。
Windows系统中有两种消息队列系统消息队列和应用程序消息队列。
计算机的所有输入设备由Windows监控。
当一个事件发生时Windows先将输入的消息放入系统消息队列中再将消息拷贝到相应的应用程序消息队列中。
应用程序的消息处理程序将反复检测消息队列并把检测到的每个消息发送到相应的窗口函数中。
这便是一个事件从发生至到达窗口函数必须经历的过程。
必须注意的是消息并非是抢占性的无论事件的缓急总是按照到达的先后派对依次处理一些系统消息除外这样可能使一些实时外部事件得不到及时处理
Windows中存在两种线程一种是用户界面线程一种是工作线程。
工作线程线程是用来执行某些辅助处理的线程它不需要进行任何系统事件或者窗口事件的处理。
用户界面线程是指拥有自己的消息循环并能对用户界面对象进行创建、交互和撤销的线程。
Windows的消息机制与用户界面线程息息相关。
用户界面线程一般是继承CWinThread类实现。
一旦一个线程调用一个与图形用户界面有关的函数(如创建窗口或者检查消息队列的函数Windows会分配给这个线程一个THREADINFO结构。
每个线程利用THREADINFO来认为自己是在一个独占的环境中运行。
在这个结构里保存了一系列的消息队列登记消息队列、发送消息队列、应答消息队列、唤醒标志、以及用来描述线程局部输入状态的若干变量。
当线程有了与之相联系的THREADINFO的结构时线程就有了自己的消息队列集合
消息种别。
这是一个数值用以标识消息。
对於每个消息息均有一个对应的识别字这些识别字定义在Windows头文件中其中大多数在WINUSER.H中以字首WM开头。
例如使用者将鼠标窗口内并按下左按钮Windows就在消息队列中放入一个消息该消息的message成员的值是WM_LBUTTONDOWN。
这是一个常数其值为0x0201。
-当一个线程调用了这个函数的时候系统要确定时哪一个线程建立了用hWnd参数标志的窗口
-系统分配内存存储消息参数将这块内存增加到相应线程的消息队列中
通过PostThreadMessage将消息放置在线程的消息队列
-可以通过GetWindowThreadProcessID来确认是哪个线程创建了窗口
-ThreadID是在线程创建的时候获得的在全系统范围内是唯一的
-要对线程编写消息循环GetMessagePeekMessage,DispatchMessage)
nExitCode向线程发送退出消息等于PostThreadMessage(ThreadID,WM_QUIT,nExitCode,0);
当我们使用PostMessage时是将一个Message复制到“登记消息队列”中然后并立即返回。
之后由GetMessage取回并响应之。
当我们使用SendMessage时我们都知道这个消息发送函数必须等到消息响应执行完毕才能返回。
而它如何做到这一点的呢当调用这个SendMessage的线程向这个线程自己创建的窗口发送消息的时候它只是调用指定窗口的窗口过程将其作为一个子例程当窗口过程完成对消息的处理时返回给SendMessage一个值。
当一个线程向其他线程创建的窗口发送消息的时候SendMessage首先将消息加入接收线程的“发送消息队列”并为这个线程设置标志。
同时发送线程将自己挂起并在自己的“应答消息队列”中加入一个等待消息。
当消息被接收线程处理完毕后窗口的返回值被登记到发送线程的应答消息队列中。
这是发送线程被唤醒取出包含在应答消息队列中的返回值。
使用GetMessage或者PeekMessage取得窗口的消息
while(GetMessage(msg,NULL,0,0))
GetMessage的特点是当线程消息队列中有消息的时候则能立刻返回否则进行等待
PeedMessage也能从线程消息队列中取得消息它的特点是不管消息队列是否存在消息都不等待。
MFC应用程序都有一个CWinApp对象继承于CWinThread在CWinApp的Run函数中进行了和GetMessage和DispatchMessage的处理,可以在MFC源代码THRDCORE.cpp找到CWinThread::Run()的代码以及Run函数的运行时机。
某些情况下你的线程不得不等待一个或多个事件并且同时等待某些Message。
MsgWaitForMultipleObjects函数非常类似WaitForMultipleObjects,但它会在“对象被激发”或者”消息到达队列”时被唤醒并且返回
MsgWaitForMultiObjects的前四个参数和WaitForMultipleObjects完全相同
参数dwWakeMask指出了想要观察的用户输入Message
MsgWaitForMultipleObjects(nEventCount,
(WAIT_OBJECT_0nEventCountdwRet)
while(PeekMessage(Msg,NULL,0,0,PM_REMOVE)
Event只能通知一件事情的发生,不能传送数据,Message可以传递简单的数据(通过LParam和WParam)
Message可以通过LParam或者WParam指向一个堆内存而达到数据通信的功能.
在某些情况下我们可能需要向其他的应用程序发送消息这时候我们可以采用SendMessage()函数向目标应用程序的某个窗口的句柄发送消息。
其中的技巧在于获取该窗口的句柄。
同时使用RegisterWindowMessage()函数创建一个唯一的消息并且两个应用程序相互都了解这条消息的含义。
同时还会用到BrodcastSystemMessage()函数它可以向系统中的每个应用程序的主窗口发送消息。
这样便可以避免出现获取另一个应用程序窗口句柄的问题。
BroadcastSystemMessage()函数提供了附加的标志BSF_LPARAMPOINTER可以将写入参数lParam的指针转化为可以被目标程序用来访问程序空间的指针但是这个标志可能尚未进行文档标准化。
首先注册自己的窗口消息。
不过我们这次不用WM_USER1的技术注册窗口消息的好处是不必费心考虑WM_USER加上某个数之后所表示的消息标识符是否超出工程的允许范围。
本例在两个工程中都使用文本字符串来注册消息。
由于这个文本字符串在整个系统中应当是唯一的因此将使用一种称为GUID的COM技术来命名消息。
GUID名字生成器程序可以在MFC的\BIN目录下找到其可执行文件名为GUIDGEN.EXE。
该程序将生成在应用程序已知范围内认为是唯一的文本字符串这对应用程序来说当然是最好不过的。
在应用程序中把GUID定义为窗口消息文本字符串:#define
“{6047CCB1-E4E7-11d1-9B7E-00AA003D8695}”
使用::RegisterWindowsMessage()注册该窗口消息文本字符串:idHelloMsg
使用::RegisterWindowsMessage()返回的消息标识符发送消息可使用以下代码:
以上代码假定事先可以通过某种方式获取目标应用程序的某个窗口的句柄。
一个指向CWnd类的指针不能在程序范围之外而发挥作用。
但是可以在CWnd
为接收已注册的窗口消息需要在接收窗口类一般为CMainFrame中手工添加ON_REGISTERED_MESSAGE消息宏到消息映射中:
该实例到目前为止一直假定事先可以通过某种方式取得目标应用程序的某个窗口的句柄。
但这是一个困难的任务。
简单的方法是向每个应用程序广播一条消息并且希望目标程序正在监听。
由于在系统中注册了一条唯一的消息因此只有目标程序会响应这条消息。
应用程序广播的消息可能是它自己的窗口句柄于是接收程序可以使用::SendMessage()来发送应答也可能是用窗口句柄来结束循环。
BSF_IGNORECURRENTTASK,dwRecipients,idHelloMsg,wParam,lParam
通过SendMessage可以把一个消息发送到另外一个进程但是在另外一个进程中试图访问LPARAM所指向的数据也许会发生错误
进程地址空间是受到保护和相互隔离的视图访问另外一个进程的地址空间是不正确的。
Windows定义了WM_COPYDATA消息专门用来在线程之间传递数据,不管两个线程是否属于一个进程
处理WM_COPYDATA的线程必须有消息队列和窗口带有消息队列的工作线程或者UI主线程)
参数cds指向一个特定的Windows数据结构COPYDATASTRUCT
}COPYDATASTRUCT,*PCOPYDATASTRUCT;
必须使用SendMessage而不是PostMessage发送WM_COPYDATA消息
WM_COPYDATA所传送的数据可以在Heap上也可以在Stack上申请因为SendMessage保证接收方在返回前完成对数据的操作。
接受方必须在WM_COPYDATA消息处理函数中完成对lpData的处理读取和保存其中的内容而不是保存lpData指针对接收方来说在这次消息处理后lpData所指向的内存将不再是可用的。
Win32进程之间有严密的保护一个进程要看到另外一个进程的地址空间中的任何一部分都是不可能的。
程序只能见到逻辑的地址所有进程的逻辑地址空间都是相同的(4GB的理论地址空间)
使用Win32进程通信技术的最低层:共享内存(SharedMemory)来进行高效的进程间数据共享
产生一个FileMapping内核对象指定共享区域大小CreateFileMapping
有些情况下由Server进程创建一个共享内存其他进程只需要找到这块共享内存并使用就可以了。
找到一个FileMapping内核对象使用OpenFileMapping
多个进程使用共享内存的时候必须保证同步安全的使用共享的内存通常使用等待被命名的Mutex来保证。
0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.
这是针对那些将内存文件映射共享给整个网络上面的应用进程使用是,
MapViewOfFile()函数负责把文件数据映射到进程的地址空间。
hFileMappingObject为CreateFileMapping()返回的文件映像对象句柄。
dwDesiredAccess则再次指定了对文件数据的访问方式而且同样要与CreateFileMapping()函数所设置的保护属性相匹配。
MapViewOfFile()函数允许全部或部分映射文件在映射时需要指定数据文件的偏移地址以及待映射的长度。
其中文件的偏移地址由DWORD型的参数dwFileOffsetHigh和dwFileOffsetLow组成的64位值来指定而且必须是操作系统的分配粒度的整数倍对于Windows操作系统分配粒度固定为64KB。
当然也可以通过如下代码来动态获取当前操作系统的分配粒度
MapViewOfFile的返回值就是被映射在进程地址空间中的共享内存块指针用户操作这个指针可以达到共享内存了。
则每个进程都必须有相同的能力产生共享内存并将它初始化。
每个进程
都应该调用CreateFileMapping(),然后调用GetLastError().如果传回的错误代码是ERROR_ALREADY_EXISTS,
那么进程就可以假设这一共享内存区域已经被别的进程打开并初始化了否则该进程就可以合理的认为自己
只有server进程才应该产生并初始化共享内存。
所有的进程都应该使用由OpenFileMapping得到的共享内存映射文件。
其中lpName是其他进程用CreateFileMapping函数创建共享内存时时指定的对象名称。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback