windows相关知识点分析
模態(tài)窗口其實(shí)就是在當(dāng)前窗口調(diào)用系統(tǒng)的消息循環(huán),響應(yīng)用戶(hù)的操作,將相關(guān)的消息發(fā)送到對(duì)應(yīng)的窗口
1:GetMessage和PeekMessage的區(qū)別?
GetMessage:獲取消息隊(duì)列中的一個(gè)消息,存入MSG中,并從消息隊(duì)列中移除,如果消息隊(duì)列中沒(méi)有消息就會(huì)阻塞;
PeekMessage:查看消息,有消息,就將數(shù)據(jù)存入MSG結(jié)構(gòu)中,沒(méi)有消息就返回FALSE,不會(huì)阻塞,但如果沒(méi)有更新區(qū),可以移除WM_PAINT消息,還可以通過(guò)最后一個(gè)參數(shù)來(lái)決定是否從隊(duì)列中移除查看的消息;
2:SendMessage和PostMessage的區(qū)別?怎么跨線(xiàn)程發(fā)消息?怎么跨進(jìn)程發(fā)消息?SendMessage在進(jìn)程間發(fā)消息要注意什么?SendMessage能將消息發(fā)送到消息隊(duì)列嗎?PostMessage可以在進(jìn)程間發(fā)消息嗎?兩個(gè)線(xiàn)程互相SendMessage會(huì)出問(wèn)題嗎?
SendMessage:將一個(gè)消息發(fā)送到指定窗口的窗口過(guò)程中,等窗口過(guò)程執(zhí)行完了再返回;
PostMessage:將消息發(fā)送到指定窗口所在線(xiàn)程的消息隊(duì)列中,直接返回,消息是否被處理完全不知道;
SendMessage直接調(diào)用窗口過(guò)程,那它是否可以將消息發(fā)送到發(fā)送到線(xiàn)程的消息隊(duì)列中呢?
可以啊,比如發(fā)送一個(gè)WM_PAINT消息,這是一個(gè)隊(duì)列消息,只有存在無(wú)效區(qū)域的情況下,才會(huì)處理WM_PAINT消息;
線(xiàn)程間SendMessage,由于它基本就是調(diào)用指定窗口的窗口過(guò)程,當(dāng)跨線(xiàn)程發(fā)消息的時(shí)候,無(wú)法調(diào)用指定窗口的窗口過(guò)程,在跨線(xiàn)程發(fā)送;
消息的時(shí)候,發(fā)送線(xiàn)程會(huì)先掛起,由系統(tǒng)線(xiàn)程將消息發(fā)送到接收線(xiàn)程的另一個(gè)隊(duì)列中,并設(shè)置QS_SENDMESSAGE標(biāo)志,當(dāng)系統(tǒng)檢測(cè)到這個(gè)標(biāo)志后,就會(huì)處理這個(gè)隊(duì)列的消息,當(dāng)這個(gè)消息被處理之后,調(diào)用SendMessage的線(xiàn)程就會(huì)被喚醒,就繼續(xù)執(zhí)行。
SendMessage是可以跨進(jìn)程發(fā)消息的,通過(guò)FindWindow找到對(duì)方進(jìn)程的窗口句柄,發(fā)一個(gè)消息過(guò)去就行了,由于兩個(gè)進(jìn)程間的內(nèi)存是完全獨(dú)立的,不能發(fā)指針,如果要發(fā)數(shù)據(jù),就用WM_COPYDATA。
PostMessage可以在進(jìn)程間發(fā)消息,但不能結(jié)合WM_COPYDATA使用,WM_COPYDATA通過(guò)內(nèi)存映射在進(jìn)程間傳遞數(shù)據(jù),PostMessage后映射文件的句柄就無(wú)效了。
兩個(gè)線(xiàn)程互相SendMessage可能會(huì)導(dǎo)致死鎖,A線(xiàn)程鎖住一個(gè)資源,向B線(xiàn)程發(fā)一個(gè)消息,A線(xiàn)程掛起,這時(shí)如果B線(xiàn)程在處理A線(xiàn)程的消息需要A線(xiàn)程鎖住的資源,A由于發(fā)給B的消息還沒(méi)有處理完就一直不能返回,鎖也沒(méi)有打開(kāi),B線(xiàn)程又用不了,消息也就處理不完,結(jié)果就死鎖了。
3:Windows是怎么實(shí)現(xiàn)窗口刷新的?怎么實(shí)現(xiàn)窗口的立即刷新?
Update Region不為空時(shí),系統(tǒng)就會(huì)自動(dòng)產(chǎn)生WM_PAINT消息,通過(guò)InvalidateRect和InvalidateRgn可把指定的區(qū)域加到窗口的Update Region中,通過(guò)處理WM_PAINT消息來(lái)實(shí)現(xiàn)窗口的刷新。?系統(tǒng)為什么不在調(diào)用Invalidate時(shí)發(fā)送WM_PAINT消息呢?又為什么非要等應(yīng)用消息隊(duì)列為空時(shí)才發(fā)送WM_PAINT消息呢?這是因?yàn)橄到y(tǒng)把在窗口中的繪制操作當(dāng)作一種低優(yōu)先級(jí)的操作,于是盡可能地推后做。不過(guò)這樣也有利于提高繪制的效率:兩個(gè)WM_PAINT消息之間通過(guò)InvalidateRect和InvaliateRgn使之失效的區(qū)域就會(huì)被累加起來(lái),然后在一個(gè)WM_PAINT消息中一次得到更新,不僅能避免多次重復(fù)地更新同一區(qū)域,也優(yōu)化了應(yīng)用的更新操作。
如果窗口更新的區(qū)域不為空,UpdateWindow函數(shù)通過(guò)發(fā)送一個(gè)WM_PAINT消息來(lái)更新指定窗口的客戶(hù)區(qū)。函數(shù)繞過(guò)應(yīng)用程序的消息隊(duì)列,直接發(fā)送WM_PAINT消息給指定窗口的窗口過(guò)程,如果更新區(qū)域?yàn)榭?#xff0c;則不發(fā)送消息。
WM_PAINT一般在消息隊(duì)列中沒(méi)有消息的時(shí)候才處理,有時(shí)候我們需要立即刷新窗口,那么就需要UpdateWindow函數(shù)了,直接繞過(guò)消息循環(huán),只要更新區(qū)域不為空,將WM_PAINT消息直接發(fā)送到指定窗口過(guò)程即可。
Invalidate(hwnd); //將窗口設(shè)為不可用,導(dǎo)致更新區(qū)域不為空
UpdateWindow(hwnd); //立即刷新窗口?
4:Windows消息循環(huán)有哪幾個(gè)函數(shù),各自的作用是什么?消息循環(huán)是怎么退出的?
while(GetMessage(&msg, NULL, 0, 0)) //獲取一個(gè)消息,成功后會(huì)放在msg中。
{ ? ? ?
?TranslateMessage(&msg); //消息進(jìn)行必要的處理轉(zhuǎn)換。 ? ??
?DispatchMessage(&msg); //調(diào)用WinProc,將msg的各項(xiàng)信息傳遞給WinProc
}
當(dāng)GetMessage獲取到的消息是WM_QUIT,返回的就是FALSE,while循環(huán)就退出了,消息循環(huán)也就終止了。
5:句柄是什么?
句柄就是一個(gè)整數(shù),Windows為每一個(gè)控件指定了一個(gè)唯一的整數(shù),通過(guò)這個(gè)整數(shù)和相關(guān)函數(shù)操作控件。
6:Windows實(shí)現(xiàn)線(xiàn)程間同步有哪些方法?實(shí)現(xiàn)進(jìn)程間同步又有哪些方法?讀寫(xiě)鎖的實(shí)現(xiàn)原理是什么?
1:volatile
2:關(guān)鍵段
3:旋轉(zhuǎn)鎖
4:讀寫(xiě)鎖
5:事件對(duì)象
6:信號(hào)量
7:互斥量
只要是內(nèi)核對(duì)象,就能用于進(jìn)程間的同步,內(nèi)核對(duì)象不屬于任何進(jìn)程,由系統(tǒng)管理。
讀寫(xiě)鎖實(shí)際是一種特殊的自旋鎖,它把對(duì)共享資源的訪問(wèn)者劃分成讀者和寫(xiě)者,讀者只對(duì)共享資源進(jìn)行讀訪問(wèn),寫(xiě)者則需要對(duì)共享資源進(jìn)行寫(xiě)操作。這種鎖相對(duì)于自旋鎖而言,能提高并發(fā)性,因?yàn)樵诙嗵幚砥飨到y(tǒng)中,它允許同時(shí)有多個(gè)讀者來(lái)訪問(wèn)共享資源,最大可能的讀者數(shù)為實(shí)際的邏輯CPU數(shù)。寫(xiě)者是排他性的,一個(gè)讀寫(xiě)鎖同時(shí)只能有一個(gè)寫(xiě)者或多個(gè)讀者(與CPU數(shù)相關(guān)),但不能同時(shí)既有讀者又有寫(xiě)者。我覺(jué)得他其實(shí)就是對(duì)關(guān)鍵段和內(nèi)核事件對(duì)象的封裝。寫(xiě)的時(shí)候獨(dú)占,讀的時(shí)候共享。
7:模態(tài)窗口的實(shí)現(xiàn)原理?模態(tài)窗口會(huì)導(dǎo)致崩潰嗎?
模態(tài)窗口其實(shí)就是在當(dāng)前窗口調(diào)用系統(tǒng)的消息循環(huán),響應(yīng)用戶(hù)的操作,將相關(guān)的消息發(fā)送到對(duì)應(yīng)的窗口。將父窗口設(shè)為不可用,即不能響應(yīng)用戶(hù)的操作,在關(guān)閉當(dāng)前窗口的時(shí)候,將父窗口設(shè)為可用,并退出消息循環(huán)。
可能導(dǎo)致窗口崩潰,模態(tài)窗口顯示的時(shí)候,除了父窗口不可用之外,其他的窗口都是可用的,如果需要的一個(gè)資源在別的地方被釋放了,而在模態(tài)窗口中使用的時(shí)候,沒(méi)有判斷可能就會(huì)導(dǎo)致崩潰。
8:你了解沙箱,UAC相關(guān)的知識(shí)嗎?
不了解
9:怎么實(shí)現(xiàn)線(xiàn)程間發(fā)消息?線(xiàn)程的消息隊(duì)列默認(rèn)會(huì)創(chuàng)建嗎?
SendMessage可以再線(xiàn)程間發(fā)消息,PostThreadMessage通過(guò)線(xiàn)程ID可以在線(xiàn)程間發(fā)消息,將消息發(fā)送到指定線(xiàn)程的消息隊(duì)列中。線(xiàn)程的消息隊(duì)列默認(rèn)是不會(huì)創(chuàng)建的,因?yàn)榫€(xiàn)程的消息隊(duì)列并不是必須的。通過(guò)ResumeThread(threadHwnd);可以創(chuàng)建線(xiàn)程的消息隊(duì)列。
10:說(shuō)說(shuō)Windows的內(nèi)存管理,怎么實(shí)現(xiàn)內(nèi)存共享?
FileMapping用于將存在于磁盤(pán)的文件放進(jìn)一個(gè)進(jìn)程的虛擬地址空間,并在該進(jìn)程的虛擬地址空間中產(chǎn)生一個(gè)區(qū)域用于“存放”該文件,這個(gè)空間就叫做 File View,系統(tǒng)并同時(shí)產(chǎn)生一個(gè)File Mapping Object(存放于物理內(nèi)存中)用于維持這種映射關(guān)系,這樣當(dāng)多個(gè)進(jìn)程需要讀寫(xiě)那個(gè)文件的數(shù)據(jù)時(shí),它們的File View其實(shí)對(duì)應(yīng)的都是同一個(gè)File ?Mapping ?Object,這樣做可節(jié)省內(nèi)存和保持?jǐn)?shù)據(jù)的同步性,并達(dá)到數(shù)據(jù)共享的目的。
總結(jié)
以上是生活随笔為你收集整理的windows相关知识点分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: vue 实现瀑布流布局的 组件/插件总汇
- 下一篇: 解决: -bash: $‘\302\24