小心Windows消息的限制

Windows提供的消息机制实在是一个好东西:

1.       消息队列是Per-Thread的,向一个消息队列投递消息,只有此消息队列对应的线程可以进行处理。

2.       消息队列是线程安全的,并发的访问会进行序列化。

3.       窗口有线程关联的,向窗口投递消息,将投递到创建这个窗口的线程对应的消息队列。

4.       Windows为那些将窗口用作线程间数据传递的应用场合,专门提供了轻量级的“Message-Only Window”:不可见、无Z-Order、不可枚举、不接收广播消息,只是进行消息分发。

5.       性能高、可靠性好(Windows的基础服务,想必也是经过无数优化了)

 

有了这些好处,消息机制往往被作为线程间通信的一种手段

 

而最近我们遇到了一个问题,与消息机制的限制有关:Windows提供的消息队列,是有10,000条的数目上限的,在MSDN上明确的写着:

 

Windows 2000/XP: There is a limit of 10,000 posted messages per message queue. This limit should be sufficiently large. If your application exceeds the limit, it should be redesigned to avoid consuming so many system resources. To adjust this limit, modify the following registry key:

HKEY_LOCAL_MACHINE

SOFTWARE

Microsoft

Windows NT

CurrentVersion

Windows

USERPostMessageLimit

The minimum acceptable value is 4000.

 

也就是说,如果消息队列中积压的消息数目超过了上限,新投递的消息将被丢弃。

 

我们的问题是这样的:

我们为了让我们的用户界面保持可响应,就把那种需要堵塞式等待的操作放到线程里。我们的TCP操作就直接放到了一个线程中,调用recv来接收网络数据,并通过向主线程Post一个消息把收到的网络数据包传递给主线程处理。而当我们使用这个TCP模块实现HTTP下载时,我们发现偶尔会出现下载的安装包损坏的问题。

经过比较,发现出现问题的安装包都是中间少了一些数据块。后来确认是由于下载速度很快,收包线程短时间将大量的消息发送到主线程,而此时如果主线程处理能力跟不上,就有可能导致消息队列被放满而出现丢包。改成直接在线程中进行TCP数据包的处理,只向主线程通知一些进度,就解决了这个问题。

 

结论:

使用Windows消息机制,要注意数目限制。

 

感受:

1.       如果使用一项技术,除了了解正常的使用方式外,还必须要了解其限制、性能,非正常使用的时候可能出现的问题。

2.       在开发中不断积累自己的经验,不要放过每一个问题,它们都可能是避免你日后出现更大问题的前车之鉴。

3.       不断学习,深刻了解学到的东西,这些都有助于你遇到问题时对问题进行正确有效的分析。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值