久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

主線程的兩個特點

 quasiceo 2017-10-22


分享到飯否

先看一段引文,出處不甚清楚,,但肯定是一本紙質(zhì)出版物,。

> 程序啟動后就執(zhí)行的那個線程稱為主線程(primary thread),主線程有兩
> 個特點,,第一,,它必須負(fù)責(zé) GUI(Graphic User Interface)程序中的主消息循
> 環(huán)。第二,,這一線程的結(jié)束(不論是因為返回或因為調(diào)用了 ExitThread())會
> 使得程序中的所有線程都被強迫結(jié)束,程序也因此而結(jié)束,。其他線程沒有機會
> 做清理工作,。

我看書的時候很少字斟句酌,一般都是只了解個大概,,而像這樣的句子就基本屬于我無視的內(nèi)容,。不過,在一個偶然的機會,,我注意到了這句話,,并有了以下這篇評論。

先說結(jié)論:句中所提到的“主線程的兩個特點”,,基本不靠譜,。

> 第一,它必須負(fù)責(zé) GUI(Graphic User Interface)程序中的主消息循環(huán),。
之所以說這句話不靠譜,,是因為它過度地限制了主線程的功能。在我的印象中,,靈圖天行者 4.0 以前的版本(含)中,,主線程是一個調(diào)度器,用于調(diào)度其余的工作線程,,而 UI 線程則亦是這些工作線程中的一個,。換句話說,,主消息循環(huán)可以不在主線程之中。

> 第二,,這一線程的結(jié)束(不論是因為返回或因為調(diào)用了 ExitThread())會使得程序中的所有線程都被強迫結(jié)束,,程序也因此而結(jié)束。
這句話半對半錯,,因為如果在主線程中調(diào)用 ExitThread 的話,,其它線程是不會退出的,因此程序也不會結(jié)束,??紤]以下代碼:

C++代碼
  1. #include <Windows.h>   
  2.   
  3. DWORD WINAPI ThreadProc(PVOID param)   
  4. {   
  5.     for (;;)   
  6.     {   
  7.         Sleep(1000);   
  8.     }   
  9.     return 0;   
  10. }   
  11.   
  12. int main(void)   
  13. {   
  14.     HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);   
  15.     Sleep(1000);   
  16.     ExitThread(0);   
  17.     return 0;   
  18. }  

程序運行后,main 所在的線程被 ExitThread 結(jié)束,,但 ThreadProc 的線程卻會一直運行,。對于這個問題,我在《Windows 編程札記》中的一段話能夠很好的解釋,,如下,。

---------- 傳說中的分隔線 ----------

那么,就讓我們來探索一下進(jìn)程正常結(jié)束的過程吧,。為了避免一切不必要代碼的干擾,,我選擇了一個空無一物的骨架程序。

C++代碼
  1. #include <Windows.h>   
  2.   
  3. int WINAPI WinMain(   
  4.     HINSTANCE hInstance,   
  5.     HINSTANCE hPrevInstance,   
  6.     LPSTR lpCmdLine,   
  7.     int nShowCmd)   
  8. {   
  9.     return 0;   
  10. }  

如你所見,,這個程序?qū)嵲谑菬o愧于“骨架”這個稱號——那真是除了骨頭就是架子了,。
從表面上來看,這個 WinMain 就是程序的入口,。當(dāng)它返回(return 0;)之后,,我們的進(jìn)程就結(jié)束了。當(dāng)然,,事實肯定沒有看起來的這么簡單,,因為編譯器是很樂于偷偷做好事的,而且做了好事還有拒不留名的習(xí)慣,。
現(xiàn)在讓我們編譯這段代碼,,并使用 WinDbg 來調(diào)試這個程序。我們不設(shè)置任何斷點,,直接讓程序運行到結(jié)束,。在這個時侯,程序的調(diào)用堆棧信息會是下面這個樣子:

WinDbg 輸出
  1. 0:000> k   
  2. ChildEBP RetAddr   
  3. 0012fdc4 7c92e89a ntdll!KiFastSystemCallRet   
  4. 0012fdc8 7c81ca3e ntdll!ZwTerminateProcess+0xc   
  5. 0012fec4 7c81ca96 kernel32!_ExitProcess+0x62   
  6. 0012fed8 004012a1 kernel32!ExitProcess+0x14
  7. 0012fee4 0040148d skeleton!__crtExitProcess+0x17   
  8. 0012ff28 004014b7 skeleton!doexit+0x113   
  9. 0012ff3c 0040114f skeleton!exit+0x11   
  10. 0012ffc0 7c816ff7 skeleton!__tmainCRTStartup+0x121   
  11. 0012fff0 00000000 kernel32!BaseProcessStart+0x23  

真相終于大白于天下,。很顯然,,編譯器把 kernel32.dll 的 ExitProcess API 藏到了 WinMain 的后面,使得我們的 skeleton.exe 進(jìn)程最終得以退出,。如果你對如何封裝 ExitProcess 的細(xì)節(jié)感興趣的話,,那么可以深入研究 Visual Studio 附帶的 C runtime 源代碼中的 crt0.c 文件,,這里就不再多介紹了。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多