第十二章 多线程与串行通信
Windows 是一个多任务操作系统。传统的 Windows 3.x 只能依靠应用程序之间的协同来
实现协同式多任务,而 Windows 95/NT 实行的是抢先式多任务。
在 Win 32(95/NT)中,每一个进程可以同时执行多个线程,这意味着一个程序可以同时
完成多个任务。对于象通信程序这样既要进行耗时的工作,又要保持对用户输入响应的应用
来说,使用多线程是最佳选择。当进程使用多个线程时,需要采取适当的措施来保持线程间
的同步。
利用 Win 32 的重叠 I/O 操作和多线程特性,程序员可以编写出高效的通信程序。在这
一讲的最后将通过一个简单的串行通信程序,向读者演示多线程和重叠 I/O 的编程技术。
12.1 多任务、进程和线程
12.1.1 Windows 3.x 的协同多任务
在 16 位的 Windows 3.x 中,应用程序具有对 CPU 的控制权。只有在调用了 GetMessage、
PeekMessage、WaitMessage 或 Yield 后,程序才有可能把 CPU 控制权交给系统,系统再把
控制权转交给别的应用程序。如果应用程序在长时间内无法调用上述四个函数之一,那么程
序就一直独占 CPU,系统会被挂起而无法接受用户的输入。
因此,在设计 16 位的应用程序时,程序员必须合理地设计消息处理函数,以使程序能
够尽快返回到消息循环中。如果程序需要进行费时的操作,那么必须保证程序在进行操作时
能周期性的调用上述四个函数中的一个。
在 Windows 3.x 环境下,要想设计一个既能执行实时的后台工作(如对通信端口的实时
监测和读写),又能保证所有界面响应用户输入的单独的应用程序几乎是不可能的。
有人可能会想到用 CWinApp::OnIdle 函数来执行后台工作,因为该函数是程序主消息循
环在空闲时调用的。但 OnIdle 的执行并不可靠,例如,如果用户在程序中打开了一个菜单
或模态对话框,那么 OnIdle 将停止调用,因为此时程序不能返回到主消息循环中!在实时
任务代码中调用 PeekMessage 也会遇到同样的问题,除非程序能保证用户不会选择菜单或弹
出模态对话框,否则程序将不能返回到 PeekMessage 的调用处,这将导致后台实时处理的中
断。
折衷的办法是在执行长期工作时弹出一个非模态对话框并禁止主窗口,在消息循环内分
批执行后台操作。对话框中可以显示工作的进度,也可以包含一个取消按钮以让用户有机会
中断一个长期的工作。典型的代码如清单 12.1 所示。这样做既可以保证工作实时进行,又
可以使程序能有限地响应用户输入,但此时程序实际上已不能再为用户干别的事情了。
清单 12.1 在协同多任务环境下防止程序被挂起的一种方法
bAbort=FALSE;
lpMyDlgProc=MakeProcInstance(MyDlgProc, hInst);
hMyDlg=CreateDialog(hInst, “Abort”, hwnd, lpMyDlgProc); //创建一个非模态对话框
ShowWindow(hMyDlg, SW_NORMAL);
评论3
最新资源