- 靜態鏈接庫和動態鏈接庫的區別
- 一個進程可以通過調用waitpid函數來等待它的子進程終止或者停止
- Debug和Release的區別
- 臨界區互斥量信號量事件進程互斥與同步
- 進程有哪幾種狀態,狀態轉換圖,及導致轉換的事件
- 進程由運行態進入就緒態和阻塞態的原因
- 進程切換
- 進程調度算法
- 死鎖
- 哲學家就餐問題
- linux運行時內存映像
- 通過虛擬地址訪問內存的優勢
- 緩存是數據交換的緩沖區(稱為Cache)
- 線程訪問某數據
- 無名管道 FIFO(命名管道)消息隊列信號量信號共享內存
1. 靜態鏈接庫和動態鏈接庫的區別:
(1) 靜態鏈接庫在編譯階段鏈接,動態鏈接庫庫在加載和運行階段鏈接。
(2) 在任何給定的文件系統中,只有動態鏈接庫的一個副本,靜態庫的內容被復制和嵌入到引用它們的每一個執行文件中
(3) 在內存中,一個動態鏈接庫的.text節的一個副本可以被不同的正在運行的進程共享;靜態鏈接庫的函數的代碼會被復制到每個運行進程的代碼段中。
(4) 如果想使用一個靜態庫的最新版本,必須顯式地將程序與更新了的庫重新鏈接;而如果想使用動態鏈接庫最新版本只需要使用動態鏈接庫的新版本替代當前的版本。
(5) 靜態鏈接庫中不能再包含其他的動態鏈接庫或者靜態庫,而在動態鏈接庫中還可以再包含其他的動態或靜態鏈接庫。
2. 進程和線程的區別:
(1) 進程是資源分配、調度的最小單位,線程是CPU調度的最小單位。
(2) 進程有自己的獨立地址空間,每啟動一個進程,系統就會為它分配地址空間,建立數據表來維護代碼段、堆棧段和數據段,這種操作非常昂貴。而線程是共享進程中的數據的,使用相同的地址空間,因此CPU切換一個線程的花費遠比進程要小很多,同時創建一個線程的開銷也比進程要小很多。
(3) 線程之間的通信更方便,同一進程下的線程共享全局變量、靜態變量等數據,而進程之間的通信需要以進程間通信的方式(IPC)進行。不過如何處理好同步與互斥是編寫多線程程序的難點。
(4) 多進程程序更健壯,多線程程序只要有一個線程死掉,整個進程也死掉了,而一個進程死掉並不會對另一個進程造成影響。
注:上述提到的資源包括可重用資源:處理器、I/O部件、內存、文件、數據庫、信號量
可消耗資源:信號、中斷、消息
3. 多進程和多線程的選擇
(1) 需要頻繁創建、銷毀的選用多線程。
(2) 需要頻繁切換的選用多線程
(3) 要求共享某些變量的選用多線程。
(4) 可能要擴展到多機分布的用多進程,多核分布的用多線程
(5) 強相關的處理用多進程,弱相關的用多線程。
4. fork函數
子進程得到與父進程用戶級虛擬地址空間相同(但是獨立的)一份副本,包括代碼和數據段、堆、共享庫以及用戶棧。子進程還獲得與父進程任何打開文件描述符相同的副本。
(1) 調用一次,返回兩次。fork函數被父進程調用一次,但是卻返回兩次——一次是返回到父進程,一次是返回到新創建的子進程。在父進程中,fork返回子進程的PID。在子進程中,fork返回0
(2) 並發執行。父進程和子進程是並發運行的獨立進程。內核能夠以任意方式交替執行它們的邏輯控制流中的指令。
(3) 相同但是獨立的地址空間。如果能夠在fork函數在父進程和子進程返回后立即暫停這兩個進程,我們會看到兩個進程的地址空間都是相同的。每個進程有相同的用戶棧、相同的本地變量值、相同的堆、相同的全局變量值,以及相同的代碼。
(4) 共享文件。子進程繼承了父進程所有的打開文件。
5. 一個進程可以通過調用waitpid函數來等待它的子進程終止或者停止。
6. Debug和Release的區別
(1) Debug:調試版本,包含調試信息,所以容量比Release版本大很多,並且不進行任何優化(優化會使調試復雜化,因為源代碼和生成的指令間關系會更復雜),便於程序員調試。Debug模式下生成兩個文件,除了.exe或.dll文件外,還有一個.pdb文件,該文件記錄了代碼中斷點等調試信息。
(2) Release:發布版本,不對源代碼進行調試,編譯時對應用程序進行優化,使得代碼大小和運行速度上都是最優的。Release模式下生成一個文件.exe或.dll文件。
7. 編譯語言和腳本語言的區別
(1)腳本語言語法簡單,比較容易掌握;編譯語言具有嚴謹,復雜語法。
(2)腳本語言在運行時被解釋器解釋成指令后立即被執行;編譯語言被編譯成可執行目標文件后被執行。
(3)因此,腳本語言不需編譯,但運行速度慢;編譯語言需要編譯,運行速度較快。
8. 線程安全
(1) 線程安全就是多線程訪問時,采用了加鎖機制(同步互斥機制),當一個線程訪問該類的某個數據時,進行保護,其他線程不能進行訪問直到該線程訪問結束,其他線程才可使用。不會出現數據不一致或者數據污染。
(2) 線程不安全就是不提供數據訪問保護,有可能出現多個線程先后更改數據造成所得到的數據是臟數據。
注:怎么判斷線程安全:多線程編程中,對類的對象的操作不需要使用額外的同步機制,也能保證對象不會處於無效狀態。
9. 臨界區
用於解決互斥問題。臨界區保證同一時刻只有一個線程可以訪問被保護起來的資源或代碼段,所有其他試圖訪問被保護起來的資源或代碼段的線程將被掛起,並一直持續到當前正在訪問被保護起來的資源或代碼段的線程訪問完畢。臨界區對象被釋放后,其他線程可以繼續搶占臨界區對象的使用。
特點:臨界區不是內核對象,不能夠用於進程之間的互斥,但臨界區更節省資源更有效率。
10. 互斥量
用於解決互斥問題。互斥量允許同一時刻只有一個進程訪問互斥資源,所有其他試圖訪問互斥資源的進程將被掛起,並一直持續到訪問互斥資源的線程訪問完畢。互斥量被釋放后,其他線程可以繼續搶占互斥資源的使用。
11. 信號量
信號量是進程間同步、互斥的一種機制。信號量允許多個進程訪問共享資源,但對同一時刻訪問共享資源的進程的數目的上限有要求。
注:
(1)在信號量上定義了三個操作:初始化、P操作、V操作
(2)P、V操作為原語操作
(3)信號量可分為二元信號量,用於解決互斥問題;多值信號量,用於解決同步問題
12. 事件
事件機制,允許一個線程在處理完一個任務后,主動喚醒另一個線程執行任務。
自動事件:當一個事件得到通知時,等待該事件的線程只有一個線程變為可調度線程。
人工事件:當一個事件得到通知時,等待該事件的所有線程均變成可調度線程。
13. 進程互斥與同步
(1)進程互斥:各進程之間競爭使用互斥資源,這一關系稱為進程互斥。
(2)進程同步:指系統中多個進程中發生的事件存在某種時序關系,需要相互合作,共同完成一項任務。
14. 進程有哪幾種狀態,狀態轉換圖,及導致轉換的事件
運行狀態:進程正在處理機上運行。在單處理機環境下,每一時刻最多只有一個進程處於運行狀態。
就緒狀態:進程已處於准備運行的狀態,即進程獲得了除處理機之外的一切所需資源,一旦得到處理機即可運行。
阻塞狀態,又稱等待狀態:進程正在等待某一事件而暫停運行,如等待某資源為可用(不包括處理機)或等待輸入/輸出完成。即使處理機空閑,該進程也不能運行。
就緒狀態 -> 運行狀態:處於就緒狀態的進程被調度后,獲得處理機資源(分派處理機時間片),於是進程由就緒狀態轉換為運行狀態。
運行狀態 -> 就緒狀態:處於運行狀態的進程在時間片用完后,不得不讓出處理機,從而進程由運行狀態轉換為就緒狀態。此外,在可剝奪的操作系統中,當有更高優先級的進程就緒時,調度程度將正執行的進程轉換為就緒狀態,讓更高優先級的進程執行。
運行狀態 -> 阻塞狀態:當進程請求某一資源(如外設)的使用和分配或等待某一事件的發生(如I/O操作的完成)時,它就從運行狀態轉換為阻塞狀態。進程以系統調用的形式請求操作系統提供服務,這是一種特殊的、由運行用戶態程序調用操作系統內核過程的形式。
阻塞狀態 -> 就緒狀態:當進程等待的事件到來時,如I/O操作結束或中斷結束時,中斷處理程序必須把相應進程的狀態由阻塞狀態轉換為就緒狀態。
15. 進程由運行態進入就緒態和阻塞態的原因
(1)時間片用完
(2)在可搶占的操作系統中,有更高優先級的進程就緒
(3)進程請求某一資源的使用和分配
(4)進程等待某一個時間的發生(如I/O操作完成)
(5)進程需要和其他進程保持同步
(6)進程運行完畢
(7)在不可搶占的操作系統中,進程由核心態轉入用戶態時系統產生一次調度,將最高優先權的就緒進程投入運行。
16. 進程切換
進程切換主要包括兩部分工作:
(1)切換全局目錄以加載一個新的地址空間
(2)切換內核棧和硬件上下文,其中硬件上下文包括了內核執行新進程需要的全部信息,如CPU相關寄存器(程序計數器、程序狀態寄存器)
注:切換過程包括了對原來運行進程各種狀態的保存和對新的進程各種狀態的恢復。
17. 進程調度算法
(1) 批處理系統中采用的調度算法:
① 先來先服務(FCFS):按進程就緒的先后順序使用CPU(非搶占式)
優缺點:公平、實現簡單、長進程后面的短進程需要等待很長時間,不利用用戶體驗
② 最短作業優先(SJF):具有最短完成時間的進程優先執行(非搶占式)
思路:先完成短的作業,改善短作業的周轉時間
優缺點:
最短的平均周轉時間:在所有進程同時可運行時,采用SJF調度算法可以得到最短的平均周轉時間
不公平:源源不斷的短任務到來,可能使長的任務長時間得不到運行->產生“飢餓”現象
③ 最短路徑剩余空間時間優先(SRTN)(搶占式)
④ 最高響應比優先:是一個綜合的算法,調度時,首先計算每個進程的響應比R;之后,總是選擇R最高的進程執行;折中權衡。
響應比R=周轉時間/處理時間=(處理時間+等待時間)/處理時間=1+(等待時間/處理時間)
(2) 交互式系統中采用的調度算法
① 時間片輪轉
目標:為短任務改善平均響應時間
解決問題的思路:周期性切換;每個進程分配一個時間片;時鍾中->輪換
時間片太長:降級為先來先服務算法;延長短作業的響應時間
時間片太短:進程頻繁切換浪費CPU時間
優缺點:公平;有利於交互式計算,響應時間快;由於進程頻繁切換,時間片輪轉算法要花費較高的開銷用於進程的切換。
② 最高優先級調度:選擇優先級最高的進程投入運行
③ 多級反饋隊列
設置多個就緒隊列,第一級隊列優先級最高。
給不同就緒隊列中的進程分配長度不同時間片,第一級隊列時間片最小;
隨着隊列優先級別的降低,時間片增大;
當第一級隊列為空時,在第二級別隊列調度,以此類推
各級隊列按照時間片輪狀方式進程調度
當一個新創建進程就緒后,進入第一級隊列
進程用完時間片而放棄CPU,進入下一級就緒隊列
由於阻塞而放棄CPU進入想用的等待隊列,一旦等待隊列發生,該進程回到原來一級就緒隊列。
④ 最短進程優先
18. 典型系統所采用的調度算法
Unix:
Windows:基於優先級的搶占式多任務調度
Linux:搶占式調度
19. 大端模式和小端模式
大端模式,是指數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中
小端模式,是指數據的低字節保存在數據的低地址中,數據的高字節保存在數據的高地址中。
20. 死鎖的概念
一組進程中,每個進程都無限等待被該組進程中的另一個進程所占有的資源,這種現象稱為進程死鎖,這一組進程被稱為死鎖進程。
21. 死鎖、活鎖和飢餓
(1)死鎖:
(2)活鎖:先加鎖,在輪詢,不斷輪詢,既無進展也沒有阻塞
(3)飢餓:持續有其他的優先級更高的進程請求相同的資源,所申請的資源一直得不到滿足。飢餓現象是由資源分配策略決定的。
22. 產生死鎖的必要條件
(1)互斥使用
一個資源每次只能給一個進程使用
(2)占有且等待
進程在申請新的資源的同時保持對原有資源的占有
(3)不可搶占
資源的申請者不能強行的從資源占有者手中奪取資源,資源只能由占有者自願釋放。
(4)循環等待
存在一個進程等待隊列{P1,P2,...,P3},
其中P1等待P2占有的資源,P2等待P3占有的資源,...,Pn等待P1占有的資源,形成一個進程等待環路。
23. 死鎖定理
(1)如果資源分配圖中沒有環路,則系統中沒有死鎖,如果圖中存在環路則系統中可能存在死鎖。
(2)如果每個資源類中只包含一個資源實例,則環路是死鎖存在的充分必要條件。
24. 解決死鎖的方法
(1)死鎖預防
靜態策略:設計合適的資源分配算法,不讓死鎖發生。
(2)死鎖避免
動態策略:以不讓死鎖發生為目標,跟蹤並評估資源分配過程,根據評估結果決策是否分配
(3)讓死鎖發生
死鎖檢測與解除
25. 死鎖預防
在設計系統時,通過確定資源分配算法,排除死鎖發生的可能性
(1)破壞“互斥使用/資源獨占”條件
資源轉換技術:把獨占資源變為共享資源
spoing技術的引入
(2)破壞“占有且等待”條件
實現方案1:要求每個進程在運行前必須一次性申請它要求的所有資源,且僅當該進程所要資源均可滿足時才給予一次性分配。
問題:資源利用率低;“飢餓”現象
實現方案2:在允許進程動態申請資源前提下規定,一個進程在申請新的資源不能立即得到滿足而變為等待狀態之前,必須釋放已占有的全部資源,若需要再重新申請。
(3)破壞“不可搶占”條件
當一個進程申請的資源被其他進程占用時,可以通過操作系統搶占這一資源(兩個進程的優先級不同)
局限性:適用於狀態易於保存和恢復的資源(CPU、內存)
(4)破壞“循環等待”條件
資源的有序分配法:把系統中所有資源編號,進程在申請資源時必須嚴格按資源編號的遞增次序進程,否則操作系統不予分配。
26. 死鎖避免
在資源動態分配過程中,防止系統進入不安全狀態,以避免發生死鎖
27. 安全狀態
安全狀態:如果系統中存在一個由所有進程構成的安全序列P1,...,Pn,則稱系統處於安全狀態。
安全序列:一個進程序列{P1,...,Pn}是安全地,如果對於沒一個進程pi(1<=i<=n);它以后還需要的資源量不超過系統當前剩余資源量與所有進程pi(j<i)當前占有資源量之和。
28. 死鎖的檢測與解除
允許死鎖的發生,但是操作系統不斷檢測死鎖是否真的發生。
一旦死鎖發生則采取專門的措施,解除死鎖並以最小的代價恢復操作系統運行。
29. 死鎖解除的辦法:
(1)撤銷所有的死鎖進程
(2)按照某種原則逐一地撤銷死鎖進程
(3)進程回退再啟動
(4)按照某種原則逐一搶占資源(資源被搶占的進程必須回退到之前的對應狀態)
30. 哲學家就餐問題
(1)最多允許4個哲學家同時坐在桌子周圍(死鎖預防)
(2)僅當一個哲學家左右兩邊的筷子都可用時,才允許它拿筷子(死鎖避免)
(3)給所有哲學家編號,奇數好的哲學家必須首先拿左邊的筷子,偶數號的哲學家則反之
31. 堆和棧的區別
(1)管理方式:棧中的空間由編譯器自動分配和釋放,堆中的空間由程序顯式地釋放和分配
(2)存儲內容:棧中存儲函數的參數值和局部變量;對中存儲動態對象
(3)空間大小:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。棧的最大容量是系統預先規定好的,在Windows下,棧的大小是2M因此,能從棧獲得的空間較小;堆是向高地址擴展的數據結構,是不連續的內存區域。堆的大小受限於計算機系統中有效的虛擬內存。能從堆獲得的空間較大。
(4)分配效率:棧由操作系統自動分配和釋放,(計算機在底層對棧提供支持)棧的分配效率比較高;堆的分配由C/C+函數庫提供,機制復雜,堆的分配效率要比棧低很多。
(5)碎片問題:對於堆來說,頻繁的new/delete操作勢必會造成內存空間的不連續,從而造成大量的碎片;棧不會產生空間碎片。
32. linux運行時內存映像
33. 一個源程序到可執行目標文件的過程
(1)預處理階段:預處理器(cpp)根據以字符#開頭的命令,修改原始的C程序。
(2)編譯階段:編譯器(ccl)將文本文件hello.i翻譯成文本文件hello.s,它包含一個匯編語言程序
(3)匯編階段:匯編器(as)將一個hello.s翻譯成機器語言指令,把這些指令打包成一個叫做可重定位目標程序的格式,並把結果保存在目標文件hello.o中。Hello.o文件是一個二進制文件。
(4)鏈接階段:生成可執行目標文件。
34. 虛擬內存
虛擬內存是計算機系統內存管理的一種技術。它使得應用程序認為它擁有連續的可用的內存,而實際上,它通常是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁盤存儲器上,在需要時進行數據交換。目前,大多數操作系統都使用了虛擬內存。
虛擬內存別稱虛擬存儲器。電腦中所運行的程序均需經由內存執行,若當前正在執行的程序占用內存很大或很多,則會導致內存消耗殆盡,為了解決該問題。Windows中運用了虛擬內存技術,即勻出一部分硬盤空間來充當內存使用。當內存耗盡時,電腦就會自動調用硬盤來充當內存,以緩解內存的緊張。
35. 通過虛擬地址訪問內存的優勢
(1)程序可以使用一系列相鄰的虛擬地址空間來訪問物理內存中不相鄰的內存緩沖區
(2)程序可以使用一系列虛擬地址來訪問大於可用物理內存的內存緩沖區。當物理內存的供應量變小時,內存管理器會將物理內存頁(通常大小為4KB)保存到磁盤文件。數據和代碼頁會根據需要在物理內存與磁盤之間移動。
(3)每個進程擁有獨立的虛擬地址空間,一個進程的代碼無法更改正在由另一個進程或操作系統使用的物理內存。因此,可以避免一個進程無意間破壞另一個進程所使用的物理內存中內容。
36. 緩存:
緩存是數據交換的緩沖區(稱為Cache),當某一個硬件要讀取數據時,會首先從緩存中查找需要的數據,如果找到了則直接執行,找不到的話則從內存中找。由於緩存的運行速度比內存的運行速度比內存快得多,故緩存的作用就是幫助硬件更快的運行。
37. 如何實現地址映射
Win32通過兩層的表結構實現地址隱射:
第一層為頁目錄表(4KB大小):分為1024個頁目錄項,每個頁目錄項對於一個頁表
第二層為頁表(4KB大小):分為1024個頁表項,每個頁表項對應一個內存頁,通過有4KB大小
32位地址:前10位為頁目錄下標,用來尋址頁目錄項,中間10位為頁表下標,用來尋址內存頁,后12位用來在物理內存頁中找到對應的字節
38. 線程訪問某數據
39. 緩存調度:
40. 緩存調度方法:
(1)FIFO
(2)LRU:最近最少使用
(3)LFU:最近使用次數最少
41. LRU實現
核心思想:“如果數據最近被訪問過,那么將來被訪問的幾率也更高”
(1)新加入的數據插入到鏈表頭部
(2)數據被訪問,將數據移動到鏈表頭部
(3)當鏈表滿,將鏈表尾部的數據丟棄
42. LFU實現
“如果數據過去被訪問多次,那么將來被訪問的頻率也更高”
(1)新加入的
43. 無名管道
管道:通常指無名管道,是UNIX系統IPC最古老的形式。
兩個局限性:
(1)單向通信
(2)只能用於具有親緣關系的進程之間
其他特點:
(3)管道的生命周期隨着進程終止而結束
(4)它可以看成是一種特殊的文件,對於它的讀寫也可以使用普通的read、write等函數。但是它不是普通的文件,並不屬於其他任何文件系統,並且只存在於內存中
44. FIFO(命名管道)
FIFO,也稱為命名管道,它是一種文件類型
FIFO的特點:
(1)它提供一個路徑名與之關聯,以FIFO的文件形式存儲於文件系統中
(2)FIFO可以用於無親緣關系的進程之間的通信
(3)按照先進先出的方式工作
45. 消息隊列
消息隊列,是消息的的鏈接表,存放在內核中。一個消息隊列由一個標識符(即隊列ID)來標識
(1)消息隊列是基於消息的(管道是基於字節流的),其中的消息具有特定的格式以及特定的優先級
(2)消息隊列獨立於發送和接收進程。進程終止時,消息隊列內容不會被刪除
(3)消息隊列可以實現消息的隨機查詢,消息不一定要以先進先出的次序讀取,也可以按消息的類型讀取
注:
消息隊列:對於每一個正在執行的Windows應用程序,系統為其建立一個“消息隊列”,用來存放可能創建的各種窗口的消息。
消息循環:應用程序中含有一段稱作“消息循環”的代碼,用來從消息隊列中檢索這些消息並把它們分發到相應的窗口函數。
46. 信號量
信號量是進程間同步、互斥的一種機制。信號量允許多個進程訪問共享資源,但對訪問共享資源的進程的數目的上限有要求。
注:
(1)在信號量上定義了三個操作:初始化、P操作、V操作
(2)P、V操作為原語操作
(3)信號量可分為二元信號量,用於解決互斥問題;多值信號量,用於解決同步問題
47. 信號
一個信號就是一個小消息,信號用於通知接受進程發生了某種類型的事件。信號是在軟件層次上對中斷機制的一種模擬。
注:
(1)發送信號
(2)接受信號
(3)處理信號(阻塞信號、執行默認行為、執行信號處理程序)
48. 共享內存
共享內存,指兩個或多個進程共享一個給定的存儲區
特點:
(1)共享內存是最快的一種IPC
對於像管道和消息隊列等進程間通信方式,需要在內核和用戶空間進行四次的數據拷貝,而共享內存則只需要拷貝兩次:一次從輸入文件到共享內存區,另一個送共享內存到輸出文件
(2)需要同步機制,以協調對共享內存的訪問
注:
(1)
(2)進程之間通過映射同一個普通文件實現共享內存,共享內存中的內容往往是在解除映射時才寫回文件
49. 套接字
與其他通信機制不同的是,它可用於不同主機的進程間的通信。
50. RPC
用於像調用本地過程一樣調用遠程過程
51. 僵屍進程、孤兒進程、守護進程
(1)僵屍進程:一個終止了但還未被回收的進程稱為僵死進程。
注:shell或者服務器,總是應該回收它們的僵死子進程。即使僵死子進程沒有運行,它們仍然消耗系統的內存資源,進程號也會被一直占用。
(2)孤兒進程:父進程執行完成或被終止后仍繼續運行的一類進程。這些孤兒進程將被init進程所收養,並由init進程對它們完成狀態收集工作。
(3)守護進程:守護進程是一類在后台運行的特殊進程,用於執行特定的系統任務。很多守護進程在系統引導的時候啟動,並且一直運行直到系統關閉。另一些只在需要的時候才啟動,完成任務后就自動結束。
52. 用戶態和內核態
內核態:CPU可以訪問內存中所有的數據,包括外設,例如硬盤、網卡,CPU也可以將自已從一個程序切換到另一個程序。
用戶態:只能受限的訪問內存,且不允許訪問外設,占用CPU的時間可以被搶占。
https://www.cnblogs.com/zemliu/p/3695503.html
53. 消息
消息,就是windows發出的一個通知,告訴應用程序某個事件發生了。例如,單擊鼠標、改變窗口尺寸、按下鍵盤上的一個鍵都會使windows發送一個消息給應用程序。
注:消息本身是作為一個記錄(結構體)傳遞給應用程序的。
54. Windows的消息系統3個組成部分
(1)消息隊列:對於每一個正在執行的Windows應用程序,系統為其建立一個“消息隊列”,用來存放可能創建的各種窗口的消息。
(2)消息循環:應用程序中含有一段稱作“消息循環”的代碼,用來從消息隊列中檢索這些消息並把它們分發到相應的窗口函數。
(3)窗口過程:每個窗口都有一個窗口過程,即一個回調函數,來接收、處理傳遞給窗口的消息。處理了一個消息后,它通常要返回一個值給windows。
55.一個消息從產生到被一個窗口響應的過程
(1)系統中發生了某個事件。
(2)Windows把這個事件翻譯為消息,然后把它放在消息隊列中。
(3)應用程序從消息隊列中接收到這個消息。
(4)應用程序把消息傳遞給一個適當的窗口的窗口過程。
(5)窗口過程響應這個消息並進行處理。
56.SendMessage和PostMessage
(1)PostMessage函數只是向線程消息隊列中添加消息,如果添加成功,則返回true,否則返回false,消息是否被處理,或處理的結果,就不知道了。
(2)SendMessage則有些不同,當線程向自己發送消息時,它並不是把消息加到隊列里,而是直接翻譯消息和調用消息處理,知道消息處理完成后才返回。所以,如果我們希望發送的消息立即被執行,就應該調用SendMessage。
(3)線程向自己發送消息時,SendMessage發送的消息不會被加入到消息隊列中,因此,不能通過PeekMessage或GetMessage獲取SendMessage發送的消息。
(4)有些消息用PostMessage不會成功。所以不是所有的消息都能夠用PostMessage。
57.為什么要用協程(進程和線程的痛點)
多線程程序設計到:
(1)鎖機制
(2)設計到線程阻塞狀態到可運行狀態之間的切換
(3)設計到線程上下文的切換
以上涉及到的任何一點,開銷都非常大的。
58. 什么是協程
協程,是一種比線程更加輕量級的存在。正如一個進程可以擁有多個線程一樣,一個線程也可以擁有多個協程。更重要的是,協程不是被操作系統內核所管理,而完全是由程序所控制。