Windows运行机理——线程的机制(1)

1. 线程的工作方式

 

线程是Windows 95的新特征,一个线程就是一个执行程序的事例。线程允许一个程序同时在多于一个以上的地方运行,这有些像多个CPU,每一个CPU执行程序的一部分。在单处理器系统中(Window 95只支持单处理器系统),只有同时处理时才出现线程。Windows 95系统中,线程之间切换CPU的间隔称为时间片(timeslicing)。因为硬件内部的计时器是以有规律的时间间隔通知操作系统的,所以操作系统可以选择不同的线程。另外,尽管16位的程序作为一个线程出现在系统线程表中,但只有Windows 32应用程序中能产生附加的线程。

一个线程被切换有两个原因,原因之一是本线程需要另一个线程先执行,此时,当前线程则把CPU让给另一个线程。另一个原因是当一个线程执行了足够长的时间后,需要把线程给另一个程序。Windows 95线程调度使用的是这样的一种算法,即把大部分时间给那些急需的线程。CPU时间间隔用硬件时钟中断,操作系统内部计时器中断处理调度决定另一个程序是否需要运行,如果运行,则切换到另一个线程上。Windows 95的时间片是20毫秒,也就是说,一秒钟内,理论上可在50个线程之间进行强制切换,但如果所有的线程都主动放弃CPU或等待系统,则切换的频率就会很高,每秒切换45千次也不奇怪。

每一个线程被分配到一个进程中,当操作系统产生一个新的进程时,也要设置一个初始线程。一个进程中的所有线程共享该进程的资源(下面要用“资源”一词来表示操作系统提供的内容),进程资源包括内存文本、文本柄和当前目录。

一般来讲,进程不交换,也不使用其他进程的资源。然而,一个进程中的多线程可能在进程资源的使用上发生冲突,这样,资源共享可能是一个混合物。例如,程序有一段代码改变了几个全局变量的代码序列,如果一个线程正好在这个序列中间被切换掉,那么下一个线程将作用这些全局变量,而且与状态不一致。成功地执行多线程程序要求你标记出一个进程中的所有的资源,这些资源需要由同步机进行监视,保证它们不会被不适宜的线程侵害。临界段(CriticalSection)和其他的线程同步机在下面进行讨论。

尽管线程共享进程资源,但每一个线程还有一定的资源提供自身,那么最重要的是吗?

不,每一个线程本身没有SS寄存器和相互依存,实际上,每一个线程在本身所在进程的地址空间内部有一个地址空间区。每一线被分配的栈区隐含值是1MB,这个容量要么在可执行文件的.DEF文件栈中,要么在调用CreateThread产生线程规定一个非零栈区。Windows 95对每一个线程栈不使用MB,而是用“guardpage(保护页)”。

2. 线程与GDI的冲突:死机的主要原因

 

很多人使用线程的时候,都喜欢在线程内画图。如果在线程内作画,程序就会很容易出错,而且还是那种没有任何响应和提示的错误问题。

例如,如下是一个文件复制的程序,这个程序由两个线程组成,一个是复制文件的线程,另一个是显示文件复制进度的过程。当文件复制一部分后,进度条就向前移动一点。理论上,这个程序没什么问题。但是,这个程序有一个很大的隐患,即主程序也可能某一时刻要更新这个进度条。例如,进度被其他窗口挡住后或者整个窗口放大缩小时,整个窗口就要刷新,这时,线程的那个部分也要刷新它,操作系统也要刷新它。这样,三个部分都要去刷新它,程序就很容易死锁。程序运行界面如图所示。


程序运行界面

这时会什么响应也没有了。这种问题在多线程中是很常见的。那怎么处理这个问题呢?

有一条原则,即程序中的线程一概不直接操作线程部分中的GDI。它只要发一个消息给主程序,让主程序绘制图形,就不会出现任何的问题了

发送消息的方法就是用PostMessage的函数。但一定不能用SendMessage。因为用PostMessage可以让主程序调度绘图,而SendMesage会立即去绘制图形。所以在线程中要避免画图,因为当作画时,程序会取得一个DC,内存中的DC表示的是一块显存。DC代表的是一个窗口,因为一个程序得到此DC时,其他程序是不能再取得DC的。以后,如果继续再取,就会进入死锁的循环内。死锁结构如图所示。

posted @ 2005-06-09 08:47  Rookie.Zhang  阅读(1423)  评论(0编辑  收藏  举报