1、什么是进程?
::一般将进程定义成一个正在运行的程序的一个实例。进程由两部分组成:
①、一个内核对象,操作系统用它来管理进程。内核对象也是系统保存进程统计信息的地方。
②、一个地址空间,其中包含所有执行体(executable)或DLL模块的代码和数据。此外,它还包含动态内存分配,比如线程堆栈和堆的分配。
进程与线程的关系:
①、一个进程创建的时候,系统会自动创建它的第一个线程,这称为主线程(primary thread)。
②、进程要做任何事情,都必须让一个线程在它的上下文中运行。如果没有线程要执行进程地址空间包含的代码,进程就失去了继续存在的理由。所以,系统会自动销毁进程及其地址空间。
③、一个进程可以有多个线程,所有线程都在进程的地址空间中“同时”执行代码。为此,每个线程都有它自己的一组CPU寄存器和它自己的堆栈。对于所有要运行的线程,操作系统会轮流为每个线程调度一些CPU时间。它会采取round-robin(轮询或轮流)方式,为每个线程都分配时间片,从而营造出所有线程都在“并发”运行的假象。
2、系统如何创建一个进程内核对象来管理每个进程。
当一个进程被初始化时,系统要为它分配一个句柄表(空的,也就是用来管理进程的内核对象)。该句柄表只用于内核对象(而不用于用户对象和gdi对象)。句柄表是一个数据结构的数组,每个结构都包含一个指向内核对象的指针,一个 访问屏蔽(DWORD)和一个标志(DWORD)。
:::当进程中的线程调用创建内核对象的函数(比如 CreatFileMapping)时,内核就为该对象分配一个内存块并对它初始化。同时对进程的句柄表进行扫描,找出一个空项,填充内核对象数据结构的内存地址到该顶的指针成员,设置访问屏蔽和标志。
::: 用于创建内核对象的所有函数均返回与进程相关的句柄。该句柄实际上是放入进程的句柄表中的索引 (由此可知,句柄是与进程相关的,不能由其他进程直接成功地使用)。但这只适用部分系统,句柄的含义可能随时变更。 应用程序在运行时有可能泄漏内核对象,但是当进程终止时系统将能确保所有内容均被正确地清除。这个情况也适用于所有对象,资源和内存块,也就是说当进程终止运行时,系统将保证进程不会留 下任何对象。
3、如何利用与一个进程关联的内核对象来操纵该进程。
4、进程的各种不同的属性(或特性),以及用于查询和更改这些属性的几个函数。
实例句柄、前一个实例句柄、进程的命令行、进程的环境变量、进程当前所在的驱动器和目录、还有版本问题等
5、如何利用一些函数在系统中创建或生成额外的进程。
我们用CreateProcess函数来创建一个进程,参考MSDN。当一个线程调用CreateProcess时,系统会做如下工作:
(1)、系统将创建一个进程内核对象,其初始使用计数为1。进程内核对象不是进程本身,而是操作系统用来管理这个进程的一个小型数据结构(该内核对象是用来管理新进程的)。
(2)、系统为新进程创建一个虚拟地址空间,并将执行体文件(和所有必要的DLL)的代码及数据加载到进程的地址空间。
(3)、系统为新进程的主线程创建一个线程内核对象(使用计数为1)。和进程内核对象一样,线程内核对象也是一个小型数据结构,操作系统用它来管理这个线程。这个主线程一开始就会执行由链接器设为应用程序入口的C/C++运行时启动例程,并最终调用你的WinMain,wWinMain,main或wmain函数。
(4)、如果系统成功创建了新进程和主线程,CreateProcess将返回TRUE。
创建子进程后:
创建一个进程内核对象时,系统会为此对象分配一个独一无二的标识符,系统中没有别的进程内核对象会有相同的ID编号
6、如何终止线程。
关闭到一个进程或线程的句柄,不会强迫系统杀死此进程或线程。关闭句柄只是告诉系统你对进程或线程的统计数据
不再感兴趣了。进程或线程会继续执行,直至自行终止。(计数,重点是计数)
进程可以通过以下4种方式终止:
(1)、主线程的入口函数返回(强烈推荐的方式)。
让主线程的入口函数返回,可以保证发生以下几件事情:
该线程创建的任何C++对象都将由这些对象的析构函数正确销毁。
操作系统将正确释放线程堆栈使用的内存。
系统将进程的退出代码(在进程内核对象中维护)设为你的入口函数的返回值。
系统递减进程内核对象的使用计数。
(2)、进程中的一个线程调用ExitProcess函数(要避免这个方式)
进程会在该进程中的一个线程调用ExitProcess函数时终止:
VOID ExitProcess(UINT fuExitCode);
一旦你的应用程序的主线程从它的入口函数返回,那么不管当前在进程中是否正在运行其他线程,都会调用ExitProcess来终止进程。不过,如果在入口函数中调用ExitThread,而不是调用ExitProcess或者简单地返回,应用程序的主线程将停止执行,但只要进程中还有其他线程正在运行,进程就不会终止。
(3)、另一个进程中的线程调用TerminateProcess函数(要避免这个方式)
调用TerminateProcess也可以终止一个进程,但是进程无法将它在内存中的任何信息转储到磁盘上。
(4)、进程中的所有线程都“自然死亡”(这是很难发生的)
posted on 2011-10-07 11:19
Yu_ 阅读(397)
评论(0) 编辑 收藏 引用 所属分类:
Windows程序设计