行程

行程中，行程本身不是基本執行單位，而是執行緒的容器。程式本身只是指令、資料及其組織形式的描述，相當於一個名詞，行程才是程式。概念.使用者下達執行程式的命令後，就會產生行程。同一程式可產生多個行程，以允許同時有多位使用者執行同一程式，卻不會相衝突。行程需要一些資源才能完成工作，如CPU使用時間、記憶體、檔案以及I/O裝置，且為依序逐一進行，也就是每個CPU核心任何時間內僅能執行一項行程。程序與執行緒的區別：程序是計算機管理執行程式的一種方式，一個程序下可包含一個或者多個執行緒。執行緒可以理解為子程序。內容.一個電腦系統行程包括下列資料：狀態.行程在執行時，狀態會改變。所謂狀態，就是指行程目前的動作：各狀態名稱可能隨不同作業系統而相異；對於單CPU系統，任何時間可能有多個行程為等待、就緒，但必定僅有一個行程在執行。注意: 程序的各個狀態之間是不能隨意切換的，例如當程序執行時因IO操作而阻塞，當IO操作完成後並不會直接恢復回執行態，而是轉為就緒態等待CPU的排程。排程.==行程間通訊（--Windows程序.作業系統使用程序ID來唯一標識每個程序。在一個程序內部，使用程序控制代碼來標識關注的每個程序。使用Windows API從程序ID獲取程序控制代碼：OpenProcess(PROCESS_ALL_ACCESS, TRUE, procId); //或者PROCESS_QUERY_INFORMATION使用API函式：GetModuleFileNameEx或GetProcessImageFileName或QueryFullProcessImageName查詢程序的exe檔名使用API函式GetCurrentProcess可以獲取本程序的偽控制代碼，只能用於本程序的API函式呼叫；不能被其他程序繼承或複製。可用API函式DuplicateHandle獲得程序的真控制代碼。使用API函式CreateProcess建立程序，WaitForSingleObject可等待子程序的結束。例如：void main() {STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory(&amp;si, sizeof(si));si.cb = sizeof(si);ZeroMemory(&amp;pi, sizeof(pi));// Start the child process.if (!CreateProcess(NULL, // No module name (use command line)"demo.exe arg1", // Command lineNULL, // Process handle not inheritableNULL, // Thread handle not inheritableFALSE, // Set handle inheritance to FALSE0, // No creation flagsNULL, // Use parent's environment blockNULL, // Use parent's starting directory&amp;si, // Pointer to STARTUPINFO structure&amp;pi) // Pointer to PROCESS_INFORMATION structure,用於給出子程序主視窗的屬性printf("CreateProcess failed (%d).\n", GetLastError());return;// Wait until child process exits.WaitForSingleObject(pi.hProcess, INFINITE);// Close process and thread handles.CloseHandle(pi.hProcess);CloseHandle(pi.hThread);建立的子程序可以繼承父程序的：子程序不能繼承：為繼承控制代碼，父程序在建立各種可繼承物件控制代碼時，在SECURITY_ATTRIBUTES結構的bInheritHandle成員為TRUE。在CreateProcess的bInheritHandles引數為TRUE；如果要繼承標準輸入、標準輸出、標準錯誤的控制代碼，STARTUPINFO結構的dwFlags成員包含STARTF_USESTDHANDLES標誌位.下述API的函式用於獲取程序相關資訊：程序終止時，所有開啟的控制代碼被關閉，程序物件被觸發而終止，退出碼是這個異常值，同時程序的所有執行中的執行緒的退出碼也是這個異常值。優雅地關閉其他程序的方法是用RegisterWindowMessage登記私有訊息，用BroadcastSystemMessage播放訊息，收到訊息的程序用ExitProcess關閉。如果想要獲取特定名字的程序的ID，需要列舉所有程序。傳統辦法是CreateToolhelp32Snapshot、Process32First、Process32Next函式；也可以使用EnumProcesses、EnumProcessModules函式來獲取所有的程序ID，一個程序的所有模組的控制代碼。示例如下：PROCESSENTRY32 pe32;HANDLE hSnaphot;HANDLE hApp;DWORD dProcess;hSnaphot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 獲取程序快照Process32First(hSnaphot, &amp;pe32); // 列舉第一個程序do {if (lstrcmpi(pe32.szExeFile, _T("NotePad.exe")) == 0) { // 查詢程序名稱為 NotePad.exedProcess = pe32.th32ProcessID;break;} while (Process32Next(hSnaphot, &amp;pe32)); // 不斷迴圈直到列舉不到程序hApp = OpenProcess(PROCESS_VM_OPERATION | SYNCHRONIZE, FALSE, dProcess); // 根據程序 ID 獲取程式的控制代碼if (!WaitForSingleObject(hApp, INFINITE)) // 等待程序關閉AfxMessageBox(" 記事本已經關閉！");// 另一種方法DWORD aProcId[1024], dwProcCnt, dwModCnt;HMODULE hMod[1000];TCHAR szPath[MAX_PATH];// 枚舉出所有程序IDif (!EnumProcesses(aProcId, sizeof(aProcId), &amp;dwProcCnt)) {//cout « "EnumProcesses error: " « GetLastError() « endl;return 0;// 遍例所有程序for (DWORD i = 0; i &lt; dwProcCnt; ++i) {// 開啟程序，如果沒有許可權開啟則跳過HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, aProcId[i]);if (NULL != hProc) {// 開啟程序的第1個Module，並檢查其名稱是否與目標相符if (EnumProcessModules(hProc, &amp;hMod, 1000, &amp;dwModCnt)) {GetModuleBaseName(hProc, hMod, szPath, MAX_PATH);if (0 == lstrcmpi(szPath, lpName)) {CloseHandle(hProc);return aProcId[i];CloseHandle(hProc);return 0;