Windows高级编程学习笔记(二)
第三章 進程
發現這本書的文字很簡練,知識點突出,而且翻譯的基本沒有拗口的地方,是本好書,(^o^)/~
下面進入正題。
關于內存映射
Windows內存管理的分頁機制在微機原理課程中有提到,后面的章節也有相關內容。這里提前寫是怕以后忘了寫出來。
一直不明白”內存映射“是怎么一回事,如很多編程資料中都會說,DLL在內存中只有一份,只是映射到不同進程的地址空間中,但是具體怎么映射的讓人只知其一不知其二。還有后面的內存映射文件到底是怎么映射的?使用分頁機制可以解釋。所謂分頁機制就是使用高速緩沖區制作一個表,先將線性地址分解成各個部分,然后分級查找到此線性地址所對應的內存頁面(通常4KB)。而這個表的內容是由操作系統來管理的。那么要實現共享DLL所在內存或者其他內存,只需要把相應的頁面地址填入進程對應的高速緩沖區中即可,這是基本原理,其中,不是頁面對其的內存是怎么處理的這些細節問題只有通過繼續學習才能知道,雖然說對于編寫程序沒什么影響,但是作為一名C/C++程序員,盡可能多地了解更多的底層知識總不是件壞事。
知識點匯總
Win32的進程是惰性的。每個進程必須擁有一個主線程(primary thread)才能工作。換句話說,Windows在創建一個進程時,同時會為此進程創建一個線程。這種處理方式把進程和線程完全分開了,能運行的只有線程,進程是線程的更大一級單位,或者說是載體。在Linux中,創建的進程是可以直接運行的,相當于主線程,這種處理方式將進程和線程區分得不是非常清楚。
WinMain函數不是GUI程序的入口點,它是由C運行時啟動函數調用的。這么說又涉及到什么是運行時啟動函數的問題。下面是我的理解:C語言編程中的main()函數大家都知道吧,這個就是入口函數。不管是運行CUI還是GUI程序,都是先進入main()函數。如果是GUI程序,main()函數會先做一些處理(初始化一些變量),然后調用WinMain函數。
了解WinMain的幾個參數。
hInstance:進程的實例句柄hInstance是一個地址,指向應用程序加載到內存時的起始地址(在此程序的線性地址空間)。它和hModule是一樣的,之所以存在兩個稱呼,是由于歷史原因在16位windows中遺留下來的稱呼,或者說為了保持兼容性而保留的。在測試時發現每次運行程序時這個值都會不一樣。
相關函數(32位windows下):- GetModuleHandle(LPCTSTR lpszModule):獲取已加載的EXE或DLL文件的起始地址。參數是模塊名稱,注意查找范圍僅限于當前進程。如果為NULL,則返回此程序EXE在內存中的起始地址。另外,如果在DLL中調用此函數,同時參數為NULL,返回的仍然是調用進程的地址,而不是DLL的基地址,和上面的結論相同。
hPrevInstance:在16位的windows下表示此應用程序的前一個運行實例,在32位下沒有此意義,只是為了兼容。
lpszCmdLine:啟動參數。非常特別需要注意的是,它總一個ANSI字符串。當你CreateProcess時,傳入的非空命令行參數也必須為ANSI字符串,否則應用程序會出錯或者崩潰。
這個lpszCmdLine和CUI的main函數的命令行參數不一樣,第一個參數(可執行文件路徑)被main除去之后傳入了WinMain。
相關函數(32bit):- LPTSTR GetCommandLine(VOID):獲取命令行指針,有ANSI版和UINCODE版。
- LPWSTR CommandLineToArgvW(LPWSTR cmdLine, LPINT pArgc):將寬字符版的命令行參數轉換成參數數組,數組個數保存在*pArgc中。
還可以使用全局變量來訪問命令行參數:_argv(原始的ANSI字符串數組),_argc。不過如果WinMain是在mian()函數中調用的,那么自然可以訪問mian()函數的兩個參數:argc, argv。
進程的環境變量。它就是一組全局字符串,由系統設置,這個字符串在注冊表中可以找到。子進程繼承自父進程,但是進程間環境變量內存區是獨立的。
相關函數:
- GetEnvironmentVariable()
- SetEnvironmentVaribale()
進程的驅動器目錄可以通過環境變量來讀寫。
相關函數:
SetCurrentDirectory()
GetFullPathName()操作系統個版本。
相關函數:
DWORD GetVersionEx(LPOSVERSIONINFO lpVersionInformation):重要函數:CreateProcess()
上一段代碼:
結束進程
三種方法:
主動調用ExitProcess()函數。
外部調用TerminateProcess()函數,不推薦使用,會導致資源不能被釋放以及DLL推出時執行的操作沒有被執行等問題。
進程中所有線程都結束,系統會自動終止進程。特別的,如果主線程是自然返回的話,系統會調用ExitProcess()自動結束進程,此時可能還有線程正在執行,它們都將被終止。如果在主線程結束時想保持其他線程繼續運行,那么需要主線程主動調用ExitThread()終止自己。
進程結束,不影響子進程。
使用WaitForSingleObject()實現阻塞調用進程直到子進程運行結束。
創建完全分離的子進程的要點是:釋放所有本進程中與子進程相關的句柄。
查看進程退出代碼或者查看進程是否終結:GetExitCodeProcess()。
總結
以上是生活随笔為你收集整理的Windows高级编程学习笔记(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米首款天玑8100手机曝光:LCD屏幕
- 下一篇: python做excel表格代码_pyt