logo资料库

《Win32多线程程序设计》文字版pdf.pdf

第1页 / 共445页
第2页 / 共445页
第3页 / 共445页
第4页 / 共445页
第5页 / 共445页
第6页 / 共445页
第7页 / 共445页
第8页 / 共445页
资料共445页,剩余部分请下载后查看
Win32多线程程序设计
作者与译者
译序
函数索引
FAQ
作者序
谁应该读这本书
关于范例程序
目录
第一篇 上路吧,线程
第1章 为什么要“千头万绪”
一条曲折的路
与线程共枕
为什么最终用户也需要多线程多任务
Win32 基础
Context Switching
Race Conditions (竞争条件)
Atomic Operations (原子操作)
线程之间如何通讯
好消息与坏消息
第2章 线程的第一次接触
产生一个线程
使用多个线程的结果
核心对象 (Kernel Objects)
线程结束代码 (Exit Code)
结束一个线程
错误处理
后台打印 (Background Printing)
成功的秘诀
第3章 快跑与等待
看似闲暇却忙碌 (Busy Waiting)
性能监视器 (Performance Monitor)
等待一个线程的结束
叮咚:被激发的对象 (Signaled Objects)
等待多个对象
在一个 GUI 程序中等待
提要
第4章 同步控制 (Synchronization)
Critical Sections (关键区域、临界区域)
死锁 (Deadlock)
哲学家进餐问题 (The Dining Philosophers)
互斥器 (Mutexes)
信号量 (Semaphores)
事件 (Event Objects)
从 Worker 线程工显示输出
Interlocked Variables
同步机制摘要
第5章 不要让线程成为脱缰野马
干净地终止一个线程
线程优先权 (Thread Priority)
初始化一个线程
提要
第6章 Overlapped I/O,在你身后变戏法
Win32 文件操作函数
被激发的 File Handles
被激发的 Event 对象
异步过程调用 (Asynchronous Procedure Calls,APCs)
对文件进行 Overlapped I/O 的缺点
I/O Completion Ports
对 Sockets 使用 Overlapped I/O
提要
第二篇 多线程程序设计的工具与手法
第7章 数据一致性 (Data Consistency)
认识 Volatile 关键字
Referential Integrity
The Readers/Writers Lock
我需要锁定吗?
Lock Granularity (锁定粒度)
提要
第8章 使用 C Run-time Library
什么是 C Runtime Library 多线程版本
选择一个多线程版本的 C Runtime Library
以 C Runtime Library 启动线程
哪一个好:CreateThread() 抑或 _beginthreadex()?
避免 stdio.h
一个安全的多线程程序
结束进程 (Process)
为什么你应该避免 _beginthread()
提要
第9章 使用 C++
处理有问题的 _beginthreadex() 函数原型
以一个 C++ 对象启动一个线程
建立比较安全的 Critical Sections
建立比较安全的 Locks
建立可互换 (Interchangeable) 的 Locks
异常情况 (Exceptions) 的处理
提要
第10章 MFC 中的线程
在 MFC 中启动一个 Worker 线程
安全地使用 AfxBeginThread() 的传回值
在 MFC 中启动一个 UI 线程
与 MFC 对象共处
MFC 的同步控制
MFC 对于 MsgWaitForMultipleObjects() 的支持
提要
第11章 GDI 与窗口管理
线程的消息队列
消息如何周游列国
GUI 效率问题
以 Worker 线程完成多线程版 MDI 程序
多个上层窗口 (Top Level Windows) 如何是好?
线程之间的通讯
NT 的影子线程 (shadow Thread)
关于 "Cancel" 对话框
锁住 GDI 对象
提要
第12章 调试
使用 Windows NT
有计划地对付错误
Bench Testing
线程对话框
运转记录 (Logging)
内存记号 (Memory Trails)
硬件调试寄存器 (Hardware Debug Registers)
科学方法
提要
第13章 进程之间的通讯 (Interprocess Communication)
以消息队列权充数据转运中心
使用共享内存 (Shared Memory)
使用指针指向共享内存 (Shared Memory)
较高层次的进程通讯 (IPC)
提要
第14章 建造 DLLs
DLL 的通告消息 (Notifications)
通告消息 (Notifications) 的问题
DLL 进入点的依序执行 (Serialization) 特性
MFC 中的 DLL 通告消息 (Notifications)
喂食给 Worker 线程
线程局部存储 (Thread Local Storage,TLS)
_declspec(thread)
数据的一致性
提要
第三篇 真实世界中的多线程应用程序
第15章 规划一个应用程序
多线程的理由
要线程还是要进程?
多线程程序的架构
评估既有程序代码的适用性
对 ODBC 做规划
第三方的函数库 (Third-Party Libraries)
提要
第16章 ISAPI
Web 服务器及其工作原理
ISAPI
IS2ODBC 范例程序
提要
第17章 OLE,ActiveX,COM
COM 的线程模型 (COM Threading Models)
AUTOINCR 范例程序
提要
附录A MTVERIFY 宏
附录B 更多的信息
Win32 多线程程序设计 线程完全手册 Multithreading Applications in Win32 The Complete Guide to Threads Jim Beveridge & Robert Wiener 著 侯 捷 译
译 序 侯 捷 thread 就是“线”。台湾计算机术语采用“绪”这个译词,“绪”就是“线” 的雅称,multithread 就是“多绪”。大陆计算机术语采用“线程”一词,multithread 就是“多线程”。 Threads(线程)是比 processes(进程)更小的执行单元,CPU 的调度与时间 分配皆以 threads 为对象。 计算机领域中早就存在 threads 的观念和技术,但是早期个人电脑操作系统(主 要是 DOS),别说 multithread,连 multitask, m ultiuser 亦不可得。因此,从当时, 乃至延伸至今,threads 的概念和功能对许多非计算机专业科班出身者而言,属于一 种“崇高而难以亲近”的位阶,对许多计算机专业科班出身者而言,却又只是“操 作系统”这门课里高高在上的一个名词。 本书第一章第一句话值得玩味:“计算机工业界每有新的技术问世,人们总是 不遗余力地去担忧它是不是够重要。公司行号虎视眈眈地注意其竞争对手,直到对 方采用并宣扬这技术有多么重要,才开始急急赶上。不论这技术是不是真的很重 要,每一个人都想尽办法让终端用户感觉真的很重要。终端用户终于真的觉得需要 它了——即使他们完全不了解那是什么东西。” threads 大约就是这么一种东西吧。OS/2、Windows NT、Windows 95 这类“新 一代 PC 操作系统”初上市时,便一再强调其抢先式多任务(preemptive multitasking) 的多线程(multithreaded)环境。拜强势行销之赐,霎时间线头到处飞舞,高深的
译序 计算机术语在街巷里弄之间传播了开来,颇有点 “Neural Fuzzy”洗衣机的味道。 这倒也算是好事! 搞不清楚 threads 是什么,对终端用户而言或许没有关系,对技术人员可就不 妙。Threads 绝对可以缩短程序的执行时间吗?应该尽量多产生 threads 来帮助程序 工作吗?任何种类的程序都可以获得 multithreads 的好处吗?错!错!错!似是而 非的观念可能会把你的程序带往更坏(而非更好)的境界。 Threads 不是新东西,但它借着 Windows 的庞大装机量初次广泛进入个人电脑 世界,带给个人电脑巨大的冲击。产生 threads 毫无困难,要让它们分工容易,而要 让它们合作,那可就得花相当多的心思。Threads 不一定带来好处,运用不当的话, 它会在执行效率上惩罚你。 Threads 是 Win32 操作系统和 Win32 程序设计不可或缺的重要环节,每一本 重量级 Win32 程序设计书籍都不会忽略这个题目(请参考附录 B)。但是这些书多 半仅以一章(甚至只是一节)来介绍这个题目。不够,真的不够,我们缺乏一本兼 具理论并重实际的 threads 专著。《Multithreading Applications in Win32 》的内容兼 具理论和实际,轻薄短小的身形则在大部头书当道的今天让我们心情轻松。这是一 本导入性书籍,在 threads 专著里算是比较容易入门的。但是你必须知道,threads 不可能让你轻松学习!同步控制、多线程通讯、数据一致性……样样耗费你的心 神,考验你专心致志的程度。读这本书,还请你武装一下自己的精神。 对于中译本,我有以下两点说明: 1. 译本内的程序实例直接取自书附光盘。如果与英文版书面代码稍有出入,恐 怕是因为作者直接在实际程序上做了点小变动而未能及时反应到书面。如果 出现这种差异,我会在程序代码列表之后以译注的方式告诉你。 2. 译本保留了相当多的原文技术术语,主要是考虑本书的潜在读者层。如果不 采用原文术语,可能各位反而要倒译回去半看半猜,那么译本的价值就适得
译序 其反了。许多地方我不厌其烦地在中文术语后面加上原文术语,为的也是同 样的原因。 3. Multithreading 非常重要。当支持多处理器(multiprocessor)的操作系统逐 渐普及时,具备多处理器的个人计算机也逐渐普及。我相信,多线程程序设 计是每一位技术人员都必须面对的技术。即便现在,多线程能够提高多人、 多任务程序的使用者接口(UI)反应度,同样也是高阶技术人员应该追求的 目标。 侯捷 新竹 1997.05.31 jjhou@jjhou.com http://www.jjhou.com(繁体中文) http://jjhou.csdn.net(简体中文)
函数索引 _beginthread.................................249 _beginthreadex.............................224 AfxBeginThread..................... 279,288 CloseHandle ...................................38 CoInitializeEx................................435 CreateEvent..................................121 CreateFile.....................................152 CreateFileMapping .......................346 CreateIoCompletionPort ...............176 CreateMutex .................................108 CreateSemaphore ........................117 CreateThread .................................26 DeleteCriticalSection ......................96 DisableThreadLibraryCalls ...........374 DllMain..........................................369 _endthread ...................................250 _endthreadex................................227 EnterCriticalSection ........................97 ExitThread ......................................45 FileIOCompletionRoutine..............164 GetExitCodeThread........................41 GetQueuedCompletionStatus.......179 GetStdHandle ...............................238 GetThreadPriority .........................141 InitializeCriticalSection....................96 InterlockedDecrement ..................126 InterlockedExchange ....................127 InterlockedIncrement ....................126 LeaveCriticalSection ...................... 97 MapViewOfFile..............................348 MsgWaitForMultipleObjects ........... 86 MsgWaitForMultipleObjectsEx ......164 OpenFileMapping..........................351 PostThreadMessage.....................315 ReadFile........................................153 ReadFileEx ...................................163 ReleaseMutex ...............................111 ReleaseSemaphore ......................119 ReplyMessage ..............................309 ResumeThread .............................145 SetThreadPriority ..........................140 SleepEx.........................................163 SuspendThread ............................146 TerminateThread ..........................132 TlsAlloc .........................................386 TlsFree..........................................388 TlsGetValue ..................................387 TlsSetValue...................................386 UnmapViewOfFile .........................353 GetOverlappedResult....................155 WaitForMultipleObjects.................. 81 WaitForMultipleObjectsEx.............164 WaitForSingleObject ...................... 72 WaitForSingleObjectEx.................163 WriteFile........................................153 WriteFileEx....................................163
常见问答集 Frequently Asked Questions FAQ 01:合作型(cooperative)多任务与抢先式(preemptive)多任务有何不同? .................................................................... 5 FAQ 02:我可以在 Win32s 中使用多个线程吗? .......................... 6 FAQ 03:线程和进程有何不同? ...................................... 10 FAQ 04:线程在操作系统中携带多少“行李”? ........................ 11 FAQ 05:Context Switch 是怎么发生的? ............................. 14 FAQ 06:为什么我应该调用 CloseHandle()? .......................... 38 FAQ 07:为什么可以在不结束线程的情况下关闭其 handle?.............. 40 FAQ 08:如果线程还在运行而我的程序结束了,会怎样? ................ 47 FAQ 09:什么是 MTVERIFY? ......................................... 48 FAQ 10:我如何得知一个核心对象是否处于激发状态? .................. 74 FAQ 11:什么是一个被激发的对象? .................................. 75 FAQ 12:“激发”对于不同的核心对象有什么不同的意义? .............. 76 FAQ 13:我如何在主线程中等待一个 handle?.......................... 85 FAQ 14:如果线程在 critical sections 中停很久,会怎样? ........... 101
viii 常见问答集(Frequently Asked Questions ) vii FAQ 15:如果线程在 critical sections 中结束,会怎样? ............. 101 FAQ 16:我如何避免死锁? ......................................... 103 FAQ 17:我能够等待一个以上的 critical sections 吗? ............... 106 FAQ 18:谁才拥有 semaphore? ...................................... 118 FAQ 19:Event object 有什么用途? ................................. 120 FAQ 20:如果我对着一个 event 对象调用 PulseEvent() 并且没有线程正在等待,会怎样? ........................... 124 FAQ 21:什么是 overlapped I/O? ................................... 150 FAQ 22:Overlapped I/O 在 Windows 95 上有什么限制? ............... 150 FAQ 23:我能够以 C runtime library 使用 overlapped I/O 吗? ........ 152 FAQ 24:Overlapped I/O 总是异步地(asynchronously)执行吗? ......... 158 FAQ 25:我应该如何为 overlapped I/O 产生一个 event 对象? .......... 159 FAQ 26:ReadFileEx()和 WriteFileEx()的优点是什么? ................ 163 FAQ 27:一个 I/O completion routine 何时被调用? .................. 163 FAQ 28:我如何把一个用户自定义数据传递给 I/O completion routine? . 165 FAQ 29:我如何把 C++ 成员函数当做一个 I/O completion routine? .... 170 FAQ 30:在一个高效率服务器(server)上我应该怎么进行 I/O? .......... 172 FAQ 31:为什么一个 I/O completion ports 是如此特殊? .............. 175 FAQ 32:一个 I/O completion port 上应该安排多少个线程等待? ....... 179 FAQ 33:为什么我不应该使用 select()? ............................. 183 FAQ 34:volatile 如何影响编译器的最优化操作? ..................... 198 FAQ 35:什么是 Readers/Writers lock? ............................. 206 FAQ 36:一次应该锁住多少数据? ................................... 215 FAQ 37:我应该使用多线程版本的 C run-time library 吗? ............ 220 FAQ 38:我如何选择一套适当的 C run-time library? ................. 221 FAQ 39:我如何使用 _beginthreadex()和 _endthreadex()? ........... 224
常见问答集(Frequently Asked Questions) ix FAQ 40:什么时候我应该使用 _beginthreadex()而非 CreateThread()? .. 227 FAQ 41:我如何使用 Console API 取代 stdio.h? ...................... 240 FAQ 42:为什么我不应该使用 _beginthread()? ...................... 248 FAQ 43:我如何以一个 C++ 成员函数当做线程起始函数?............... 256 FAQ 44:我如何以一个成员函数当做线程起始函数? ................... 261 FAQ 45:我如何能够阻止一个线程杀掉它自己? ....................... 282 FAQ 46:CWinApp 和主线程之间有什么关系? ......................... 290 FAQ 47:我如何设定 AfxBeginThread()中的 pThreadClass 参数? ....... 293 FAQ 48:我如何对一个特定的线程调试? ............................. 324 FAQ 49:如果一个新的线程使用了我的 DLL,我如何被告知?............ 370 FAQ 50:为什么我在写 DLL 时需要小心所谓的动态链接? ............... 376 FAQ 51:为什么我在 DllMain 中启动一个线程时必须特别小心? ......... 379 FAQ 52:我如何在 DLL 中设定一个 thread local storage(TLS)? ....... 389 FAQ 53:_declspec(thread)的限制是什么? .......................... 392 FAQ 54:我应该在什么时候使用多线程? ............................. 398 FAQ 55:我能够对既有程序代码进行多线程操作吗? ................... 406 FAQ 56:我可以在我的数据库应用程序中使用多线程吗?............................... 411
分享到:
收藏