1、线程的组成
(1)、一个是线程的内核对象,操作系统用它管理线程。内核对象还是系统用来存放线程统计信息的地方。
(2)、一个线程堆栈,用于维护线程执行时所需的所有函数参数和局部变量。
2、线程的运行
线程要在其进程的地址空间内执行代码和处理数据。所以,假如一个进程上下文中有两个以上的进程运行,这些线程将共享同一个地址空间。这些线程可以执行同样的代码,可以处理相同的数据。此外,这些线程还共享内核对象句柄,因为句柄表是针对每一个进程的,而不是针对每一个线程。
3、线程的创建、
(1)、如果应用程序中有多个线程函数,必须为它们指定不同的名称,否则编译器/链接器会认为你创建了一个函数的多个实现。
(2)、你的线程函数(实际就是你的所有函数)应该尽可能使用函数参数和局部变量。使用静态和全局变量时,多个线程可以同时访问这些变量,这样可能会破坏变量中保存的内容。然而,参数和局部变量是在线程堆栈上创建的。因此,不太可能被其他线程破坏。
(3)、使用CreateThread、_beginthreadex创建,没什么好说的。
4、终止线程
(1)、线程函数返回(这是强烈推荐的)。
这是保证线程的所有资源都被正确清理的惟一方式。让线程函数返回,可以确保以下正确的应用程序清理工作都得以执行:
线程函数中创建的所有C++对象都通过其析构函数被正确销毁。
操作系统正确释放线程堆栈使用的内存。
操作系统把线程的退出代码(在线程的内核对象中维护)设为线程函数的返回值。
系统递减少线程的内核对象的使用计数。
(2)、线程通过调用ExitThread函数“杀死”自己(要避免使用这种方法)。
导致操作系统清理该线程使用的所有操作系统资源。但是,你的C/C++资源(如C++类对象)不会被销毁。
(3)、同一个进程或另一个进程中的线程调用TerminateThread函数(要避免使用这种方法)。
TerminateThread函数是异步的。也就是说,它告诉系统你想终止线程,但在函数返回时,并不
保证线程已经终止了。如果需要确定线程已终止运行,还需要调用WaitForSingleObject。
(4)、包含线程的进程终止运行(这种方法避免使用)。
ExitProcess和TerminateProcess函数也可用于终止线程的运行。区别在于,这些函数会使终止运行的进程中的所有线程全部终止。同时,由于整个进程都会关闭,所以它所使用的所有资源肯定都会被清理。其中必然包括所有线程的堆栈。这两个函数会导致进程中剩余的所有线程被强行“杀死”,这就好象是我们为剩余的每个线程都调TerminateThread。
显然,这意味着正确的应用程序清理工作不会执行:C++对象的析构函数不会被调用,数据不会回写到磁盘……等等。
正如我在本章开始就解释的一样,当应用程序的入口函数返回时,C/C+运行库的启动代码将调用ExitProcess。因此,如果应用程序中并发运行着多个线程,你需要在主线程返回之前,显式地处理好每个线程的终止过程。否则,其他所有正在运行的线程都会在毫无预警的前提下突然“死亡”。
posted on 2011-10-07 23:10
Yu_ 阅读(248)
评论(0) 编辑 收藏 引用 所属分类:
Windows程序设计