CreateProcess 函数 实例 记事本
在程序设计时,某一个具体的功能模块可以通过函数或是线程等不同的形式来实现。对于同一进程而言,这些函数、线程都是存在于同一个地址空间下的,而且在执行时,大多只对与其相关的一些数据进行处理。如果算法存在某种错误,将有可能破坏与其同处一个地址空间的其他一些重要内容,这将造成比较严重的后果。为保护地址空间中的内容可以考虑将那些需要对地址空间中的数据进行访问的操作部分放到另外一个进程的地址空间中运行,并且只允许其访问原进程地址空间中的相关数据。具体的,可在进程中通过CreateProcess()函数去创建一个子进程,子进程在全部处理过程中只对父进程地址空间中的相关数据进行访问,从而可以保护父进程地址空间中与当前子进程执行任务无关的全部数据。对于这种情况,子进程所体现出来的作用同函数和线程比较相似,可以看成是父进程在运行期间的一个过程。为此,需要由父进程来掌握子进程的启动、执行和退出。下面这段代码即展示了此过程:
// 临时变量 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); // 启动"记事本"作为子进程 BOOL ret = CreateProcess(NULL, cCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (ret) { // 关闭子进程的主线程句柄 CloseHandle(pi.hThread); // 等待子进程的退出 WaitForSingleObject(pi.hProcess, INFINITE); // 获取子进程的退出码 GetExitCodeProcess(pi.hProcess, &dwExitCode); // 关闭子进程句柄 CloseHandle(pi.hProcess); }
此段代码首先通过CreateProcess()创建Windows自带的“记事本”程序为子进程,子进程启动后父进程通过WaitForSingleObject()函数等待其执行的结束,在子进程没有退出前父进程是一直处于阻塞状态的,这里子进程的作用同单线程中的函数类似。一旦子进程退出,WaitForSingleObject()函数所等待的pi.hProcess对象将得到通知,父进程将得以继续,如有必要可以通过GetExitCodeProcess()来获取子进程的退出代码。
相比而言,更多的情况是父进程在启动完子进程后就再不与其进行任何数据交换和通讯,由其创建的子进程的执行成功与否均与父进程无关。许多大型软件在设计时也多采用了这类思想,将某些功能完全通过独立的应用程序来完成,当需要执行某操作时只要通过主程序启动相应的子进程即可,具体的处理工作均由子进程去完成。这类子进程的创建过程更为简单,例如对于上面那段代码只需去除对子进程句柄pi.hProcess的等待即可:
BOOL ret = CreateProcess(NULL, cCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (ret) { // 关闭子进程的主线程句柄 CloseHandle(pi.hThread); // 关闭子进程句柄 CloseHandle(pi.hProcess); }