如何得到 windows 线程消息队列的长度?就是里面还有多少消息没取出来?

Rain7758 2011-07-19 03:05:07
系统是否有 API 可以获取,我查了下 MSDN 是没有的,GetQueueStatus 也取不到。

先来段测试 GetQueueStatus 的代码:

DWORD dwCurThreadID = GetCurrentThreadId();
int i = 0;
for (; i < INT_MAX; ++i)
{
// if (!PostMessage(WM_USER, 1, 2))
if (!PostThreadMessage(dwCurThreadID, WM_USER, 1, 2))
{
break;
}
}
DWORD dwCountAllEvents = 0xFFFF & GetQueueStatus(QS_ALLEVENTS);
DWORD dwCountALLINPUT = 0xFFFF & GetQueueStatus(QS_ALLINPUT);
DWORD dwCountQS_ALLPOSTMESSAGE = 0xFFFF & GetQueueStatus(QS_ALLPOSTMESSAGE);
CString str;
str.Format(_T("Queue Length: %d \r\n dwCountAllEvents: %u \r\n dwCountALLINPUT: %u \r\n dwCountQS_ALLPOSTMESSAGE: %u ")
, i, dwCountAllEvents, dwCountALLINPUT, dwCountQS_ALLPOSTMESSAGE
);
AfxMessageBox(str);


上面代码只得到了最大长度 10000,结果:
---------------------------
testThreadMessageQueue
---------------------------
Queue Length: 10000

dwCountAllEvents: 58

dwCountALLINPUT: 0

dwCountQS_ALLPOSTMESSAGE: 256
---------------------------
确定
---------------------------
...全文
798 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
lxk899 2012-07-17
  • 打赏
  • 举报
回复
我觉得我们可以设定个计数器吧,调用PostThreadMessage的时候是该计数器加1,调用GetMessage返回后减1;这个计数器的值就应该是线程队列的长度吧。
roamyuan15 2011-11-21
  • 打赏
  • 举报
回复
楼主,现在有新的研究成果了吗?我现在也遇到相同的问题,因为我怀疑自己扔了太多的消息进入了消息队列,然后程序效率有问题。可是我得不到某一时刻消息队列中消息的数量,以下是我的想法,可是结果不是
int i = 0;
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
++i;
}
树先生1991 2011-07-26
  • 打赏
  • 举报
回复
应lz要求 jf
Lactoferrin 2011-07-23
  • 打赏
  • 举报
回复
看那个不如看源代码
Rain7758 2011-07-23
  • 打赏
  • 举报
回复
咦,没人进来接分啊,莫非是题目太高调了。。。
schlafenhamster 2011-07-23
  • 打赏
  • 举报
回复
windows早期默认的线程消息队列的最大长度好像是8,
现在已经无限了。
Eleven 2011-07-23
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 lactoferrin 的回复:]
看那个不如看源代码
[/Quote]
GetMessage/PeekMessage的实现里应该有吧~
kyotrue 2011-07-21
  • 打赏
  • 举报
回复
我是来接分的
Lactoferrin 2011-07-21
  • 打赏
  • 举报
回复
其实这些泄露的windows2000源代码里面都有
许文君 2011-07-21
  • 打赏
  • 举报
回复
9l还算有些意思,其他我怎么看都像是从看雪复制来的,一字未变,所以啊...以后还是先用搜索引擎然后才是论坛
呔妖怪来嘛 2011-07-20
  • 打赏
  • 举报
回复
public: Message* GetAllMessages() [];
这样返回消息数组
之后只需要取数组长度
能行吗
Rain7758 2011-07-20
  • 打赏
  • 举报
回复
目前的唯一解就是,封装 POST ,然后自己使用计数器。。。
POST 的时候 InterlockedIncrement,GetMessage 处理的时候 InterlockedDecrement
Rain7758 2011-07-20
  • 打赏
  • 举报
回复
看看这帖子,有价值的回复基本上都是我自己的研究,呵呵
最终方案倾向于:
POST 的时候 InterlockedIncrement,GetMessage 处理的时候 InterlockedDecrement



散分了,要分的赶紧回复!
许文君 2011-07-20
  • 打赏
  • 举报
回复
你翻的看雪的老贴把?链表难道不是在内存?windows默认的线程消息队列的最大长度好像是8,
Rain7758 2011-07-20
  • 打赏
  • 举报
回复

下面是 windows 内核实现的细节,内核结构中明明有队列长度,MS 却不暴露,有以下可能:
一是为了兼容性,可能其他版本windows没有;
二是可能因为该值变化太快;
三是有些消息不会进队列:http://msdn.microsoft.com/en-us/library/ms644927%28v=VS.85%29.aspx#sending_messages

Windows XP SP2, the message queue is found at offset 0xD0 of _W32THREAD, and looks like:

typedef struct _MSG_QUEUE {PMSG_QUEUE_ENTRY Head;PMSG_QUEUE_ENTRY Tail;unsigned long NumberOfMessages;} MSG_QUEUE;Each queue entry, in turn, looks like:

typedef struct _MSG_QUEUE_ENTRY {PMSG_QUEUE_ENTRY pNext;PMSG_QUEUE_ENTRY pPrev;struct _MSG { unsigned long hWnd; unsigned long ulMsg; unsigned long wParam; unsigned long lParam; unsigned long time; // In milliseconds POINT pt; // Mouse cursor position unsigned long dwUnknown; unsigned long dwExtraInfo; } Msg;} MSG_QUEUE_ENTRY, * PMSG_QUEUE_ENTRY;So for each thread, we can just start at the head of the queue, and keep following pNext until we get to the end, at which point pNext will be NULL.
Rain7758 2011-07-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xuddk727 的回复:]
消息队列无非就一内存块,windows内部应该还封装了一道指针用于获取队列中下一成员,不知道哪儿有反汇编的代码,研究一下就知道了。
[/Quote]

据逆向的同仁说,是个链表
Lactoferrin 2011-07-20
  • 打赏
  • 举报
回复
windows research kernel?那个没有win32子系统的
ladingwen3 2011-07-20
  • 打赏
  • 举报
回复
微软似乎已经完全公开xp的源代码了,供教学使用。潘爱民老师在博客中说过。

也可以看看潘老师的《windows 内核原理与实现》这本书。

许文君 2011-07-20
  • 打赏
  • 举报
回复
消息队列无非就一内存块,windows内部应该还封装了一道指针用于获取队列中下一成员,不知道哪儿有反汇编的代码,研究一下就知道了。
Rain7758 2011-07-19
  • 打赏
  • 举报
回复
回复楼上的,现在就是要用,不是“一般不用”。。。
加载更多回复(1)

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧