VC++中進(jìn)程與多進(jìn)程管理的方法
發(fā)布時(shí)間:2008/8/23 0:00:00 訪問次數(shù):662
進(jìn)程是當(dāng)前操作系統(tǒng)下一個被加載到內(nèi)存的、正在運(yùn)行的應(yīng)用程序的實(shí)例。每一個進(jìn)程都是由內(nèi)核對象和地址空間所組成的,內(nèi)核對象可以讓系統(tǒng)在其內(nèi)存放有關(guān)進(jìn)程的統(tǒng)計(jì)信息并使系統(tǒng)能夠以此來管理進(jìn)程,而地址空間則包括了所有程序模塊的代碼和數(shù)據(jù)以及線程堆棧、堆分配空間等動態(tài)分配的空間。進(jìn)程僅僅是一個存在,是不能獨(dú)自完成任何操作的,必須擁有至少一個在其環(huán)境下運(yùn)行的線程,并由其負(fù)責(zé)執(zhí)行在進(jìn)程地址空間內(nèi)的代碼。在進(jìn)程啟動的同時(shí)即同時(shí)啟動了一個線程,該線程被稱作主線程或是執(zhí)行線程,由此線程可以繼續(xù)創(chuàng)建子線程。如果主線程退出,那么進(jìn)程也就沒有存在的可能了,系統(tǒng)將自動撤消該進(jìn)程并完成對其地址空間的釋放。
加載到進(jìn)程地址空間的每一個可執(zhí)行文件或動態(tài)鏈接庫文件的映象都會被分配一個與之相關(guān)聯(lián)的全局唯一的實(shí)例句柄(hinstance)。該實(shí)例句柄實(shí)際是一個記錄有進(jìn)程加載位置的基本內(nèi)存地址。進(jìn)程的實(shí)例句柄在程序入口函數(shù)winmain()中通過第一個參數(shù)hinstance hinstexe傳遞,其實(shí)際值即為進(jìn)程所使用的基本地址空間的地址。對于vc++鏈接程序所鏈接產(chǎn)生的程序,其默認(rèn)的基本地址空間地址為0x00400000,如沒有必要一般不要修改該值。在程序中,可以通過getmodulehandle()函數(shù)得到指定模塊所使用的基本地址空間。
子進(jìn)程的創(chuàng)建
進(jìn)程的創(chuàng)建通過createprocess()函數(shù)來實(shí)現(xiàn),createprocess()通過創(chuàng)建一個新的進(jìn)程及在其地址空間內(nèi)運(yùn)行的主線程來啟動并運(yùn)行一個新的程序。具體的,在執(zhí)行createprocess()函數(shù)時(shí),首先由操作系統(tǒng)負(fù)責(zé)創(chuàng)建一個進(jìn)程內(nèi)核對象,初始化計(jì)數(shù)為1,并立即為新進(jìn)程創(chuàng)建一塊虛擬地址空間。隨后將可執(zhí)行文件或其他任何必要的動態(tài)鏈接庫文件的代碼和數(shù)據(jù)裝載到該地址空間中。在創(chuàng)建主線程時(shí),也是首先由系統(tǒng)負(fù)責(zé)創(chuàng)建一個線程內(nèi)核對象,并初始化為1。最后啟動主線程并執(zhí)行進(jìn)程的入口函數(shù)winmain(),完成對進(jìn)程和執(zhí)行線程的創(chuàng)建。
createprocess()函數(shù)的原型聲明如下:
bool createprocess(
lpctstr lpapplicationname, // 可執(zhí)行模塊名
lptstr lpcommandline, // 命令行字符串
lpsecurity_attributes lpprocessattributes, // 進(jìn)程的安全屬性
lpsecurity_attributes lpthreadattributes, // 線程的安全屬性
bool binherithandles, // 句柄繼承標(biāo)志
dword dwcreationflags, // 創(chuàng)建標(biāo)志
lpvoid lpenvironment, // 指向新的環(huán)境塊的指針
lpctstr lpcurrentdirectory, // 指向當(dāng)前目錄名的指針
lpstartupinfo lpstartupinfo, // 指向啟動信息結(jié)構(gòu)的指針
lpprocess_information lpprocessinformation // 指向進(jìn)程信息結(jié)構(gòu)的指針
);
在程序設(shè)計(jì)時(shí),某一個具體的功能模塊可以通過函數(shù)或是線程等不同的形式來實(shí)現(xiàn)。對于同一進(jìn)程而言,這些函數(shù)、線程都是存在于同一個地址空間下的,而且在執(zhí)行時(shí),大多只對與其相關(guān)的一些數(shù)據(jù)進(jìn)行處理。如果算法存在某種錯誤,將有可能破壞與其同處一個地址空間的其他一些重要內(nèi)容,這將造成比較嚴(yán)重的后果。為保護(hù)地址空間中的內(nèi)容可以考慮將那些需要對地址空間中的數(shù)據(jù)進(jìn)行訪問的操作部分放到另外一個進(jìn)程的地址空間中運(yùn)行,并且只允許其訪問原進(jìn)程地址空間中的相關(guān)數(shù)據(jù)。具體的,可在進(jìn)程中通過createprocess()函數(shù)去創(chuàng)建一個子進(jìn)程,子進(jìn)程在全部處理過程中只對父進(jìn)程地址空間中的相關(guān)數(shù)據(jù)進(jìn)行訪問,從而可以保護(hù)父進(jìn)程地址空間中與當(dāng)前子進(jìn)程執(zhí)行任務(wù)無關(guān)的全部數(shù)據(jù)。對于這種情況,子進(jìn)程所體現(xiàn)出來的作用同函數(shù)和線程比較相似,可以看成是父進(jìn)程在運(yùn)行期間的一個過程。為此,需要由父進(jìn)程來掌握子進(jìn)程的啟動、執(zhí)行和退出。下面這段代碼即展示了此過程:
// 臨時(shí)變量
cstring scommandline;
char cwindowsdirectory[max_path];
char ccommandline[max_path];
dword dwexitcode;
process_information pi;
startupinfo si = {sizeof(si)};
// 得到windows目錄
getwindowsdirectory(cwindowsdirectory, max_path);
// 啟動"記事本"程序的命令行
scommandline = cstring(cwindowsdirectory) + "\\notepad.exe";
::strcpy(ccommandline, scommandline);
// 啟動"記事本"作為子進(jìn)程
bool ret = createprocess(null, ccommandline, null, null, false, 0, null, null, &si, pi);
if (ret) {
// 關(guān)閉子進(jìn)程的主線程句柄
closehandle(pi.hthread);
// 等待子進(jìn)程的退出
waitforsingleobject(pi.hprocess, infinite);
// 獲取子進(jìn)程的退出碼
getexitcodeprocess(pi.hprocess, &dwexitcode);
// 關(guān)閉子進(jìn)程句柄
close
進(jìn)程是當(dāng)前操作系統(tǒng)下一個被加載到內(nèi)存的、正在運(yùn)行的應(yīng)用程序的實(shí)例。每一個進(jìn)程都是由內(nèi)核對象和地址空間所組成的,內(nèi)核對象可以讓系統(tǒng)在其內(nèi)存放有關(guān)進(jìn)程的統(tǒng)計(jì)信息并使系統(tǒng)能夠以此來管理進(jìn)程,而地址空間則包括了所有程序模塊的代碼和數(shù)據(jù)以及線程堆棧、堆分配空間等動態(tài)分配的空間。進(jìn)程僅僅是一個存在,是不能獨(dú)自完成任何操作的,必須擁有至少一個在其環(huán)境下運(yùn)行的線程,并由其負(fù)責(zé)執(zhí)行在進(jìn)程地址空間內(nèi)的代碼。在進(jìn)程啟動的同時(shí)即同時(shí)啟動了一個線程,該線程被稱作主線程或是執(zhí)行線程,由此線程可以繼續(xù)創(chuàng)建子線程。如果主線程退出,那么進(jìn)程也就沒有存在的可能了,系統(tǒng)將自動撤消該進(jìn)程并完成對其地址空間的釋放。
加載到進(jìn)程地址空間的每一個可執(zhí)行文件或動態(tài)鏈接庫文件的映象都會被分配一個與之相關(guān)聯(lián)的全局唯一的實(shí)例句柄(hinstance)。該實(shí)例句柄實(shí)際是一個記錄有進(jìn)程加載位置的基本內(nèi)存地址。進(jìn)程的實(shí)例句柄在程序入口函數(shù)winmain()中通過第一個參數(shù)hinstance hinstexe傳遞,其實(shí)際值即為進(jìn)程所使用的基本地址空間的地址。對于vc++鏈接程序所鏈接產(chǎn)生的程序,其默認(rèn)的基本地址空間地址為0x00400000,如沒有必要一般不要修改該值。在程序中,可以通過getmodulehandle()函數(shù)得到指定模塊所使用的基本地址空間。
子進(jìn)程的創(chuàng)建
進(jìn)程的創(chuàng)建通過createprocess()函數(shù)來實(shí)現(xiàn),createprocess()通過創(chuàng)建一個新的進(jìn)程及在其地址空間內(nèi)運(yùn)行的主線程來啟動并運(yùn)行一個新的程序。具體的,在執(zhí)行createprocess()函數(shù)時(shí),首先由操作系統(tǒng)負(fù)責(zé)創(chuàng)建一個進(jìn)程內(nèi)核對象,初始化計(jì)數(shù)為1,并立即為新進(jìn)程創(chuàng)建一塊虛擬地址空間。隨后將可執(zhí)行文件或其他任何必要的動態(tài)鏈接庫文件的代碼和數(shù)據(jù)裝載到該地址空間中。在創(chuàng)建主線程時(shí),也是首先由系統(tǒng)負(fù)責(zé)創(chuàng)建一個線程內(nèi)核對象,并初始化為1。最后啟動主線程并執(zhí)行進(jìn)程的入口函數(shù)winmain(),完成對進(jìn)程和執(zhí)行線程的創(chuàng)建。
createprocess()函數(shù)的原型聲明如下:
bool createprocess(
lpctstr lpapplicationname, // 可執(zhí)行模塊名
lptstr lpcommandline, // 命令行字符串
lpsecurity_attributes lpprocessattributes, // 進(jìn)程的安全屬性
lpsecurity_attributes lpthreadattributes, // 線程的安全屬性
bool binherithandles, // 句柄繼承標(biāo)志
dword dwcreationflags, // 創(chuàng)建標(biāo)志
lpvoid lpenvironment, // 指向新的環(huán)境塊的指針
lpctstr lpcurrentdirectory, // 指向當(dāng)前目錄名的指針
lpstartupinfo lpstartupinfo, // 指向啟動信息結(jié)構(gòu)的指針
lpprocess_information lpprocessinformation // 指向進(jìn)程信息結(jié)構(gòu)的指針
);
在程序設(shè)計(jì)時(shí),某一個具體的功能模塊可以通過函數(shù)或是線程等不同的形式來實(shí)現(xiàn)。對于同一進(jìn)程而言,這些函數(shù)、線程都是存在于同一個地址空間下的,而且在執(zhí)行時(shí),大多只對與其相關(guān)的一些數(shù)據(jù)進(jìn)行處理。如果算法存在某種錯誤,將有可能破壞與其同處一個地址空間的其他一些重要內(nèi)容,這將造成比較嚴(yán)重的后果。為保護(hù)地址空間中的內(nèi)容可以考慮將那些需要對地址空間中的數(shù)據(jù)進(jìn)行訪問的操作部分放到另外一個進(jìn)程的地址空間中運(yùn)行,并且只允許其訪問原進(jìn)程地址空間中的相關(guān)數(shù)據(jù)。具體的,可在進(jìn)程中通過createprocess()函數(shù)去創(chuàng)建一個子進(jìn)程,子進(jìn)程在全部處理過程中只對父進(jìn)程地址空間中的相關(guān)數(shù)據(jù)進(jìn)行訪問,從而可以保護(hù)父進(jìn)程地址空間中與當(dāng)前子進(jìn)程執(zhí)行任務(wù)無關(guān)的全部數(shù)據(jù)。對于這種情況,子進(jìn)程所體現(xiàn)出來的作用同函數(shù)和線程比較相似,可以看成是父進(jìn)程在運(yùn)行期間的一個過程。為此,需要由父進(jìn)程來掌握子進(jìn)程的啟動、執(zhí)行和退出。下面這段代碼即展示了此過程:
// 臨時(shí)變量
cstring scommandline;
char cwindowsdirectory[max_path];
char ccommandline[max_path];
dword dwexitcode;
process_information pi;
startupinfo si = {sizeof(si)};
// 得到windows目錄
getwindowsdirectory(cwindowsdirectory, max_path);
// 啟動"記事本"程序的命令行
scommandline = cstring(cwindowsdirectory) + "\\notepad.exe";
::strcpy(ccommandline, scommandline);
// 啟動"記事本"作為子進(jìn)程
bool ret = createprocess(null, ccommandline, null, null, false, 0, null, null, &si, pi);
if (ret) {
// 關(guān)閉子進(jìn)程的主線程句柄
closehandle(pi.hthread);
// 等待子進(jìn)程的退出
waitforsingleobject(pi.hprocess, infinite);
// 獲取子進(jìn)程的退出碼
getexitcodeprocess(pi.hprocess, &dwexitcode);
// 關(guān)閉子進(jìn)程句柄
close
熱門點(diǎn)擊
- CPLD開發(fā)板和FPGA開發(fā)板的區(qū)別
- 基于FPGA和AD1836的I2S接口設(shè)計(jì)
- vc中如何使用設(shè)備描述表
- Visual C++中調(diào)用DLL實(shí)現(xiàn)數(shù)據(jù)加密
- Visual C++6.0 API函數(shù)操作技
- VC++中進(jìn)程與多進(jìn)程管理的方法
- JavaCard CPU的設(shè)計(jì)與FPGA實(shí)現(xiàn)
- 如何用C語言開發(fā)DSP嵌入式系統(tǒng)
- C和C++ 字符串字面量的比較
- Xilinx針對Virtex-5 FXT F
推薦技術(shù)資料
- 聲道前級設(shè)計(jì)特點(diǎn)
- 與通常的Hi-Fi前級不同,EP9307-CRZ這臺分... [詳細(xì)]
- 電源管理 IC (PMIC)&
- I2C 接口和 PmBUS 以及 OTP/M
- MOSFET 和柵極驅(qū)動器單
- 數(shù)字恒定導(dǎo)通時(shí)間控制模式(CO
- Power Management Buck/
- 反激變換器傳導(dǎo)和輻射電磁干擾分析和抑制技術(shù)
- 多媒體協(xié)處理器SM501在嵌入式系統(tǒng)中的應(yīng)用
- 基于IEEE802.11b的EPA溫度變送器
- QUICCEngine新引擎推動IP網(wǎng)絡(luò)革新
- SoC面世八年后的產(chǎn)業(yè)機(jī)遇
- MPC8xx系列處理器的嵌入式系統(tǒng)電源設(shè)計(jì)
- dsPIC及其在交流變頻調(diào)速中的應(yīng)用研究