防假死一周研究报告

本文探讨了浏览器防假死的实现方式,尤其是Chrome与其他基于IE内核浏览器的区别。作者通过实验发现,Chrome能完美防假死是因为其窗口与线程的处理方式,而在同一窗口的子父窗口可能导致消息循环合并,造成假死问题。尽管尝试使用PeekMessage来解决,但最终未能找到理想解决方案。代码示例展示了子窗口线程如何影响主窗口的响应情况。
摘要由CSDN通过智能技术生成

目前我所知的,能防假死的浏览器有:Chrome,Maxthon,Theworld,搜狗.除了Chrome外,其余的都是IE内核,它们的实现方式都是一样的,页面窗口与主程序窗口分离,每个页面一个线程.事实上,除了Chrome能完美实现防假死,其余都有瑕疵.

瑕疵有3

  1. 点击主窗口的时候,发现页面失去了输入焦点
  2. 按alt+tab键切换窗口的时候,发现第一次不能成功,按两次才行
  3. 弹出的模态窗口并不模态,主窗口仍能动,其他页面也能动

造成这些瑕疵,还是因为页面窗口与主程序窗口分离,问题是为什么不能在同一个窗口呢?实验证明,放在同一个窗口,即使是不同进程,子窗口处于假死状态的话,主窗口也同样假死了.

 

这一周,我一直在尝试一个事情,子窗口假死的时候,主窗口能否不死,两个窗口是处于不同线程.

测试内容如下:有窗口A和窗口B,A是由主线程创建,然后创建一个线程,再这个线程上创建B,CreateWindow的hWndParent参数是A的hwnd.显然A,B都有各自的消息循环,但当B执行一个死循环的时候,A也死掉,没有反应了,但如果B的hWndParent是NULL的话,当B无响应时,A仍然能活动自如.于是猜测是当两个窗口处于父子关系时,它们的消息循环是否合并了?

但,后来翻遍了资料,都没有讲两个不同线程的子父窗口的消息循环是怎样的.

 

最后发现在B执行死循环操作的时候,如果添加PeekMessage函数,那么A是可以正常响应的.PeekMessage是什么?就是在消息队列中把消息提出来,可以把消息清除,也可以不清除(使用PM_REMOVE 或 PM_NOREMOVE)标记.但如果不清除,A仍然是不能响应.于是可以猜测,当这两个窗口处于父子关系的时候,主进程会先将它们的消息放在同一队列中,然后再分发给各自的线程,所以当B堵塞的时候,A就无法响应,只有将属于B的消息都清除掉,A的消息才能到达A.

确实是这样吗?找不到资料,不能确定.

 

如果猜测是正确的,那么就要想办法将B的消息从消息队列中清除掉,而这个操作只能在另一个线程中,但PeekMessage做的只是当前线程的,也没有别的函数可以做到.

看来,目前来说,实验结果是不成功.

 

其实也是,Maxthon,Theworld,搜狗都不是省油的灯,他们肯定也想过,不得已才采用这个"分离"的办法.但为何Chrome能做到?不要忘了,那可是google的孩子,另外Chrome采用的是开源的核心,在处理这个事情上更方便.

 

最后附上测试代码,很混乱,见谅.

 

 

 

// MyWin.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include <windows.h>
#define  szClassMain "MainWClass"
#define  szClassChild "ChildWClass"

// Global variable
 
HINSTANCE hinst;
HWND hParent;
HWND hChild,hChild2;
HANDLE hTh1;
DWORD hThID1;
HHOOK hMsgHook;

// Function prototypes.
 
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
InitApplication(HINSTANCE);
InitInstance(HINSTANCE, int);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
BOOL WINAPI ThreadProc(HWND);
BOOL WINAPI ThreadProc2(HWND);
LRESULT CALLBACK GetMsgProc(int,WPARAM ,LPARAM );

// Application

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值