您现在的位置是: 软件 > 开发者网络 > 程序方舟 > 系统编程 > 正文


-Win xp中的多种网络
-试验试验试验试验
-用Freehand实现位图矢量化
-网络电话面面观

WIN32程序设计之线程
2001-05-28· ·QQ新人类编译··yesky

1 2 3 4  下一页


  线程是Win32 API中最为令人激动和有用的特性之一。线程可让你将一个程序分解成多个线程来执行。在这篇文章中你将学习到在Win32程序中创建线程的基本概念。

  可能用到线程的地方

  在你的程序中,有不少地方都可能要用到线程:

  .如果你创建一个MDI(Multiple Document Interface,多文档界面)的应用。对于每个窗口都分配一个独立的线程是很有用的。例如,一个让你通过多个modem同时连接到多个主机的MDI通信程序,对于连接一个主机的每个窗口,如果都拥有自己的线程,就能让设计得到很大的简化。

  .在一个程序中,如果包含有复杂的图形(例如一个CAD/CAM程序,在一个复杂的画图中,可能需要画10,000线来刷新显示),它将要使用一个很长的时间来刷新显示,通过在后台中创建一个独立的线程来处理重绘,将会是很有用的,而用户界面也拥有自己的线程,由于通过后台的线程重绘,前台的线程可很好地响应用户的操作。

  .在一个复杂的模拟程序中,例如是一个模拟生物在某个环境活动的程序,如果每个实体都拥有自己的线程,通常可简化程序的设计。由于每个实体都是与其它的实体无关,因此可以独立响应各自的模拟事件;

  .如果你程序中的某部分需要很快地响应某些高优先权的事件,这个问题可通过使用线程优先权的办法来解决。代码中高优先权的部分放在它自己的线程中,并且该线程拥有一个比同一机器中的其它线程更高的优先权。高优先权的线程将等待必要的事件发生。当它察觉到该事件发生,它将会被唤醒并且使用可以得到的几乎全部的CPU周期来进行处理,直到该任务全部完成。然后它可以恢复到休眠的状态,并等待下一事件的来临。

  .如果你使用一个多处理器的机器,并且想利用所有CPU的处理性能,你可以将该应用分解成多个线程。NT划分CPU的单元是线程,因此如果你的应用只拥有一个线程,在默认的状态下,只会用到一个CPU来处理。如果将程序分解为多个线程,NT将可以把线程分配到不同的CPU上运行。

  .任何需要“在后台”处理,而前台需要响应用户操作的任务,使用线程来设计就更简单。例如,你可以将繁重的计算、页面格式化操作、文件读写等放在独立的线程中,并放在后台处理,这样就可以减少对前台用户操作的影响。

  介绍

  如果你使用过UNIX、VMS或者大型机系统,那么多线程可能对你来说已经是一个熟悉的概念。如果你只用过MS-DOS的话,多线程对你来说或许是一个新事物。我们首先从一个操作系统的角度来讨论一下多进程和多线程。

  MS-DOS是一个单进程的操作系统。它每次只能运行一个程序。你装入一个程序--工作--退出,然后运行另一个。在某些情况下,TSR或许有点多进程的影子,不过TSR通常导致的问题表明多进程只是MS-DOS的一个幻想。

  微软的Windows 3.1以及苹果的Macintosh系统都属于协作型的多任务操作系统。两者都可以在同一时间运行多个程序(进程)。例如,你可以在一个窗口中运行一个字处理程序,在另一个窗口中运行一个电子制表程序,然后在第三个出口运行一个从BBS上下载文件的程序。称为协作型的原因,是由于每个程序都要负责在适当的时间正确地放弃控制,以令所有的进程看起来都在同时工作。不过,一个长时间的磁盘访问或者有一个程序在进行不可中断的任务处理,都将会独占系统一段时间,从而令协作暂停。这些情况令协作型的多任务系统在很多情况下都是不可行的。只要有一个程序挂起,整个系统都会因此而崩溃。这是由于该程序挂起时,它将不可以放弃控制,这样所有的处理都会停下来。

  UNIX是一个抢先型的多任务系统,它可以为全部在运行的进程都分配一定的CPU时间,并且尽量做到最恰当。UNIX给一个进程一段的CPU时间--可能是20毫秒左右--在这段时间到期后,操作系统将会收回处理器的控制,并且将下一段的CPU时间分配给另一个进程。因此一个UNIX机器即使同时运行几百个进程,也可以令用户感到很流畅。如果一个进程挂起的话,对其它进程也不会有影响,因为CPU时间的控制仍然掌握在操作系统上。

  Windows NT和Windows95是一个抢先型多任务、多线程操作系统。因为它使用抢先型的多任务,所以它拥有与UNIX同样平滑的处理和进程独立。多线程就更进一步。一个独立的程序默认是使用一个线程,不过它可以将自己分解为几个独立的线程来执行,例如,其中的一个线程可以发送一个文件到打印机,而另一个可以响应用户的输入。这个简单的程序设计修改可以明显减少用户等待的时间,让用户无需担心长时间的计算、重绘屏幕、文件读写等带来的不便。

  多线程还可以让你从许多高端的多处理器NT机器中得到好处。例如,你购买了一个高级的RISC机器,可以使用多达10个CPU芯片,但在开始的时候你只购买了一个CPU。你写了一个简单的Mandelbrot set程序,你发现需要15秒的时间来重新绘制Mandelbrot set的画面。

  现在你在机器中多加9个CPU。当你再次运行这个Mandelbrot程序的时候,你会发现它仍然需要15秒的时间来执行。NT可以做到在不同的CPU上运行不同的线程,不过它在一个单线程的程序中,只能为它分配一个CPU,NT不可以将一个单线程的处理分配到多个CPU上。由于NT自身的多线程,Mandelbrot程序还是会快一点的,因为它不会与NT系统的线程竞争CPU时间。因此,在一个10CPU的机器上,除非程序是多线程的,否则任何一个程序都不会占用超过十分之一的CPU处理能力。

  如果你将Mandelbrot程序多线程化,NT就可以在不同的CPU上运行独立的线程,并且让程序得到全部CPU处理性能的好处。例如,如果该Mandelbrot程序将自己分解为10个线程,然后每个线程都在一个CPU上运行,该程序的运行速度将会快10倍。在一个10CPU的机器上,使用超过10个的线程是没有意义的,因为每个线程都会带来一点系统开销,因此使用超过10个线程是有点浪费的。不过,你喜欢的话,或者更多的线程可以令设计思路更简单,你可以将程序分解为100个线程,或者画每条扫描线都使用一个线程。事实上,确实有不少的设计通过将一个应用分解为多个的线程,从而令整个的程序更易懂,而且线程是很容易创建的。

  在NT中,进程可没有线程那样吸引人。一个程序可创建一个独立的进程,不过新的进程是完全和以前的程序无关的。在UNIX中,一个新的进程可获得原有进程变量空间的一个完全拷贝,而NT与UNIX不同,一个新的进程至多可以继承特别指示处理的拷贝。你通常会使用进程的情况是,你想在某个程序中启动另一个独立的程序。例如,如果你要写自己的程序管理器或者文件管理器,你将使用进程来在这些程序中启动其它的应用。

  NT启动进程时,默认只使用一个线程执行。例如,当你在命令行打“notepad”或者在程序管理器中双击notepad(记事本)的图标,NT创建一个进程,并且该进程拥有一个线程来“运行”notepad的代码。该进程事实上就是该应用拥有的全局变量、环境字符串和堆栈的一个容器,而线程就是用来真正执行代码的。

  在一个进程中的所有线程都分享他们父进程的变量空间。每个线程都拥有它们自己的堆栈。当你在一个进程中创建一个新的线程时,它可以访问到父进程所有的全局变量和堆栈。由于现在多个线程都可以独立修改同一个全局变量,因此程序中在处理全局变量时要比较小心,否则很容易带来问题。为了解决这种情况可能带来的问题,Win32 API内置有同步的技术,可以确保你独占访问全局的值。

1 2 3 4  下一页

【责任编辑:方舟】
【发表评论】【关闭窗口】
■ 相关内容
 Win32程序设计之网络通信
 Win32程序设计之系统安全
 Win32程序设计之服务
感谢 访问天极网,如果您觉得该文章涉及版权问题,请看这里!