windows消息機制的有趣發現(一)

最近琢磨windows的消息機制,發現一些有趣的地方,可能是對的,也可能是錯的,分享出來讓大家評判評判。

1:每個線程都有消息隊列

不僅僅是有窗口的線程,沒有窗口的線程也有消息隊列!編寫一個win32控制檯程序,代碼如下:

#include<windows.h>

void main()
{   
	DWORD dwThread = GetCurrentThreadId();
	::PostThreadMessage(dwThread,10000,NULL,NULL);
	MSG msg;
	GetMessage(&msg,NULL,NULL,NULL);
}

 

獲取當前線程ID,對當前線程發送線程消息,然後調用GetMessage函數從消息隊列中取消息,看看能不能取到我們之前發出的編號爲10000的消息。

運行發現GetMessage函數成功從消息隊列中取出了我們發送的編號爲10000的消息!我們這個線程沒有窗口、沒有消息循環,但是有消息隊列,消息隊列是windows爲線程提供的。

2:消息隊列的容量有多大?

如果我們不停的發送消息,卻不用GetMessage之類的函數獲取並從消息隊列中移除消息。消息隊列中的消息豈不是越來越多?那麼這個消息隊列究竟有多大容量呢?它最多能容納多少消息?我們編寫如下代碼

#include<windows.h>

void main()
{   
	DWORD dwThread = GetCurrentThreadId();
	for (int i=0;i<1000;i++)
	PostThreadMessage(dwThread,10000,NULL,NULL);
	int n = 0;
	MSG msg;
	while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
	{
		if (msg.message == 10000)
			n++;
	}

}

循環調用PostThreadMessage發送1000個消息,然後用PeekMessage取出消息,最後一個參數PM_REMOVE說明每取出一個消息後將該消息從消息隊列中移除。我們用變量n來統計從消息隊列中取出了多少個編號爲10000的消息。這裏爲什麼不用GetMessage呢?因爲GetMessage把消息隊列中的消息取完了以後會阻塞起來一直等待,我們的while循環無法退出,後面的斷點也無法命中。而PeekMessage把消息隊列中的消息取完了以後,取不到消息就返回0,我們的while也就結束了。

運行後發現,果然,n的值爲1000,取出了1000個我們發送的消息。接下來我們再增大消息的發送數量,看看還能取出多少。

這次我們發送了50000個消息,但是運行後發現只從消息隊列中取出了10000個消息!消息隊列的容量爲10000個嗎?我們上網查資料,確實如此。消息隊列的容量默認爲10000個,這個值可以在註冊表中修改。

展開註冊表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\

找到USERPostMessageLimit 項,發現該項的默認值爲10000。我們可以通過修改該值來改變消息隊列的容量,重啓後生效。

 

 


 

發佈了63 篇原創文章 · 獲贊 86 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章