进程
进程是当前操作系统下一个被加载到内存的、正在运行的应用程序的实例。每一个进程都是由内核对象和地址空间所组成的,内核对象可以让系统在其内存放有关进程的统计信息并使系统能够以此来管理进程,而地址空间则包括了所有程序模块的代码和数据以及线程堆栈、堆分配空间等动态分配的空间。进程仅仅是一个存在,是不能独自完成任何操作的,必须拥有至少一个在其环境下运行的线程,并由其负责执行在进程地址空间内的代码。在进程启动的同时即同时启动了一个线程,该线程被称作主线程或是执行线程,由此线程可以继续创建子线程。如果主线程退出,那么进程也就没有存在的可能了,系统将自动撤消该进程并完成对其地址空间的释放。
加载到进程地址空间的每一个可执行文件或动态链接库文件的映象都会被分配一个与之相关联的全局唯一的实例句柄(Hinstance)。该实例句柄实际是一个记录有进程加载位置的基本内存地址。进程的实例句柄在程序入口函数WinMain()中通过第一个参数HINSTANCE hinstExe传递,其实际值即为进程所使用的基本地址空间的地址。对于VC++链接程序所链接产生的程序,其默认的基本地址空间地址为0x00400000,如没有必要一般不要修改该值。在程序中,可以通过GetModuleHandle()函数得到指定模块所使用的基本地址空间。
子进程的创建
进程的创建通过CreateProcess()函数来实现,CreateProcess()通过创建一个新的进程及在其地址空间内运行的主线程来启动并运行一个新的程序。具体的,在执行CreateProcess()函数时,首先由操作系统负责创建一个进程内核对象,初始化计数为1,并立即为新进程创建一块虚拟地址空间。随后将可执行文件或其他任何必要的动态链接库文件的代码和数据装载到该地址空间中。在创建主线程时,也是首先由系统负责创建一个线程内核对象,并初始化为1.最后启动主线程并执行进程的入口函数WinMain(),完成对进程和执行线程的创建。
CreateProcess()函数的原型声明如下:
BOOL CreateProcess( LPCTSTR lpApplicationName, // 可执行模块名 LPTSTR lpCommandLine, // 命令行字符串 LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程的安全属性 LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性 BOOL bInheritHandles, // 句柄继承标志 DWORD dwCreationFlags, // 创建标志 LPVOID lpEnvironment, // 指向新的环境块的指针 LPCTSTR lpCurrentDirectory, // 指向当前目录名的指针 LPSTARTUPINFO lpStartupInfo, // 指向启动信息结构的指针 LPPROCESS_INFORMATION lpProcessInformation // 指向进程信息结构的指针 ); |
// 临时变量 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); |