进程:一个程序在数据集合上的一次运行过程;由两部分组成,一个是进程内核对象,另一个是地址空间。
线程:是"进程"中某个单一顺序的控制流;也由两部分组成,一个是线程内核对象(线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构),另一个是线程堆栈(包括函数参数跟局部变量)。
每当进程被初始化时,系统就要创建一个主线程,
主线程的进入点函数:即m a i n、w m a i n、Wi n M a i n或w Wi n M a i n。
创建线程
C r e a t e T h r e a d函数是用来创建线程的Wi n d o w s函数。不过,如果你正在编写C / C + +代码,决不应该调用C r e a t e T h r e a d。相反,应该使用Visual C++运行期库函数_ b e g i n t h r e a d e x。
终止线程
线程函数返回(最好使用这种方法):
在线程函数中创建的所有C + +对象均将通过它们的撤消函数正确地撤消。
操作系统将正确地释放线程堆栈使用的内存。
系统将线程的退出代码(在线程的内核对象中维护)设置为线程函数的返回值。
系统将递减线程内核对象的使用计数。
通过ExitThread函数线程自行取消(不推荐):
该函数将终止线程的运行,并导致操作系统清除该线程使用的所有操作系统资源。但是,C + +资源(如C + +类对象)将不被撤消。该线程的内存堆栈会被撤消。
同一个进程或另一个进程中的线程调用Te r m i n a t e T h r e a d函数(不推荐):
与E x i t T h r e a d不同,E x i t T h r e a d总是撤消调用的线程,而Te r m i n a t e T h r e a d能够撤消任何线程。
Te r m i n a t e T h r e a d函数是异步运行的函数,也就是说,它告诉系统你想要线程终止运行,但是,当函数返回时,不能保证线程被撤消。如果需要确切地知道该线程已经终止运行,必须调用Wa i t F o r S i n g l e O b j e c t 或者类似的函数,传递线程的句柄。
线程的内核对象的使用计数会被递减,但是,在拥有线程的进程终止运行之前,系统不撤消该线程的堆栈。
包含线程的进程终止(应该避免):
E x i t P r o c e s s和Te r m i n a t e P r o c e s s函数也可以用来终止线程的运行。
Kernel32.dll中的BaseThreadStart函数实际上是线程开始执行的地方,然后转移到_ t h r e a d s t a r t e x。
线程的句柄
HANDLE GetCurrentProcess();HANDLE GetCurrentThread();这两个函数可以获得句柄,但只是伪句柄。
有时可能需要获得线程的实句柄而不是它的伪句柄。所谓“实句柄”,我是指用来明确标识一个独一无二的线程的句柄。
通常可以使用DuplicateHandle这个函数,用与另一个进程相关的内核对象来创建一个与进程相关的新句柄。由于D u p l i c a t e H a n d l e会递增特定对象的使用计数,因此当完成对复制对象句柄的使用时,应该将目标句柄传递给C l o s e H a n d l e,从而递减对象的使用计数,这一点很重要。
还要指出,D u p l i c a t e H a n d l e除了用于线程,还可以用来将进程的伪句柄转换成进程的实句柄。
阅读(1732) | 评论(0) | 转发(0) |