爱问 爱问共享资料 爱问分类
首页 >IT资料 >IT书籍 >Win32多线程程序设计.pdf

Win32多线程程序设计.pdf举报

简介:

win32程序,共同探讨

Win32多线程程序设计线程完全手册MultithreadingApplicationsinWin32TheCompleteGuidetoThreadsJimBeveridge&RobertWiener著侯捷译译序侯捷thread就是“线”。台湾计算机术语采用“绪”这个译词,“绪”就是“线”的雅称,multithread就是“多绪”。大陆计算机术语采用“线程”一词,multithread就是“多线程”。Threads(线程)是比processes(进程)更小的执行单元,CPU的调度与时间分配皆以threads为对象。计算机领域中早就存在threads的观念和技术,但是早期个人电脑操作系统(主要是DOS),别说multithread,连multitask,multiuser亦不可得。因此,从当时,乃至延伸至今,threads的概念和功能对许多非计算机专业科班出身者而言,属于一种“崇高而难以亲近”的位阶,对许多计算机专业科班出身者而言,却又只是“操作系统”这门课里高高在上的一个名词。本书第一章第一句话值得玩味:“计算机工业界每有新的技术问世,人们总是不遗余力地去担忧它是不是够重要。公司行号虎视眈眈地注意其竞争对手,直到对方采用并宣扬这技术有多么重要,才开始急急赶上。不论这技术是不是真的很重要,每一个人都想尽办法让终端用户感觉真的很重要。终端用户终于真的觉得需要它了——即使他们完全不了解那是什么东西。”threads大约就是这么一种东西吧。OS/2、WindowsNT、Windows95这类“新一代PC操作系统”初上市时,便一再强调其抢先式多任务(preemptivemultitasking)的多线程(multithreaded)环境。拜强势行销之赐,霎时间线头到处飞舞,高深的译序计算机术语在街巷里弄之间传播了开来,颇有点“NeuralFuzzy”洗衣机的味道。这倒也算是好事!搞不清楚threads是什么,对终端用户而言或许没有关系,对技术人员可就不妙。Threads绝对可以缩短程序的执行时间吗?应该尽量多产生threads来帮助程序工作吗?任何种类的程序都可以获得multithreads的好处吗?错!错!错!似是而非的观念可能会把你的程序带往更坏(而非更好)的境界。Threads不是新东西,但它借着Windows的庞大装机量初次广泛进入个人电脑世界,带给个人电脑巨大的冲击。产生threads毫无困难,要让它们分工容易,而要让它们合作,那可就得花相当多的心思。Threads不一定带来好处,运用不当的话,它会在执行效率上惩罚你。Threads是Win32操作系统和Win32程序设计不可或缺的重要环节,每一本重量级Win32程序设计书籍都不会忽略这个题目(请参考附录B)。但是这些书多半仅以一章(甚至只是一节)来介绍这个题目。不够,真的不够,我们缺乏一本兼具理论并重实际的threads专著。《MultithreadingApplicationsinWin32》的内容兼具理论和实际,轻薄短小的身形则在大部头书当道的今天让我们心情轻松。这是一本导入性书籍,在threads专著里算是比较容易入门的。但是你必须知道,threads不可能让你轻松学习!同步控制、多线程通讯、数据一致性……样样耗费你的心神,考验你专心致志的程度。读这本书,还请你武装一下自己的精神。对于中译本,我有以下两点说明:1.译本内的程序实例直接取自书附光盘。如果与英文版书面代码稍有出入,恐怕是因为作者直接在实际程序上做了点小变动而未能及时反应到书面。如果出现这种差异,我会在程序代码列表之后以译注的方式告诉你。2.译本保留了相当多的原文技术术语,主要是考虑本书的潜在读者层。如果不采用原文术语,可能各位反而要倒译回去半看半猜,那么译本的价值就适得译序其反了。许多地方我不厌其烦地在中文术语后面加上原文术语,为的也是同样的原因。3.Multithreading非常重要。当支持多处理器(multiprocessor)的操作系统逐渐普及时,具备多处理器的个人计算机也逐渐普及。我相信,多线程程序设计是每一位技术人员都必须面对的技术。即便现在,多线程能够提高多人、多任务程序的使用者接口(UI)反应度,同样也是高阶技术人员应该追求的目标。侯捷新竹1997.05.31jjhou@jjhou.comhttp://www.jjhou.com(繁体中文)http://jjhou.csdn.net(简体中文)函数索引_beginthread.................................249LeaveCriticalSection......................97_beginthreadex.............................224MapViewOfFile..............................348AfxBeginThread.....................279,288MsgWaitForMultipleObjects...........86CloseHandle...................................38MsgWaitForMultipleObjectsEx......164CoInitializeEx................................435OpenFileMapping..........................351CreateEvent..................................121PostThreadMessage.....................315CreateFile.....................................152ReadFile........................................153CreateFileMapping.......................346ReadFileEx...................................163CreateIoCompletionPort...............176ReleaseMutex...............................111CreateMutex.................................108ReleaseSemaphore......................119CreateSemaphore........................117ReplyMessage..............................309CreateThread.................................26ResumeThread.............................145DeleteCriticalSection......................96SetThreadPriority..........................140DisableThreadLibraryCalls...........374SleepEx.........................................163DllMain..........................................369SuspendThread............................146_endthread...................................250TerminateThread..........................132_endthreadex................................227TlsAlloc.........................................386EnterCriticalSection........................97TlsFree..........................................388ExitThread......................................45TlsGetValue..................................387FileIOCompletionRoutine..............164TlsSetValue...................................386GetExitCodeThread........................41UnmapViewOfFile.........................353GetQueuedCompletionStatus.......179GetOverlappedResult....................155GetStdHandle...............................238WaitForMultipleObjects..................81GetThreadPriority.........................141WaitForMultipleObjectsEx.............164InitializeCriticalSection....................96WaitForSingleObject......................72InterlockedDecrement..................126WaitForSingleObjectEx.................163InterlockedExchange....................127WriteFile........................................153InterlockedIncrement....................126WriteFileEx....................................163常见问答集FrequentlyAskedQuestionsFAQ01:合作型(cooperative)多任务与抢先式(preemptive)多任务有何不同?....................................................................5FAQ02:我可以在Win32s中使用多个线程吗?..........................6FAQ03:线程和进程有何不同?......................................10FAQ04:线程在操作系统中携带多少“行李”?........................11FAQ05:ContextSwitch是怎么发生的?.............................14FAQ06:为什么我应该调用CloseHandle()?..........................38FAQ07:为什么可以在不结束线程的情况下关闭其handle?..............40FAQ08:如果线程还在运行而我的程序结束了,会怎样?................47FAQ09:什么是MTVERIFY?.........................................48FAQ10:我如何得知一个核心对象是否处于激发状态?..................74FAQ11:什么是一个被激发的对象?..................................75FAQ12:“激发”对于不同的核心对象有什么不同的意义?..............76FAQ13:我如何在主线程中等待一个handle?..........................85FAQ14:如果线程在criticalsections中停很久,会怎样?...........101viii常见问答集(FrequentlyAskedQuestions)FAQ15:如果线程在criticalsections中结束,会怎样?.............101FAQ16:我如何避免死锁?.........................................103FAQ17:我能够等待一个以上的criticalsections吗?...............106FAQ18:谁才拥有semaphore?......................................118FAQ19:Eventobject有什么用途?.................................120FAQ20:如果我对着一个event对象调用PulseEvent()并且没有线程正在等待,会怎样?...........................124FAQ21:什么是overlappedI/O?...................................150FAQ22:OverlappedI/O在Windows95上有什么限制?...............150FAQ23:我能够以Cruntimelibrary使用overlappedI/O吗?........152FAQ24:OverlappedI/O总是异步地(asynchronously)执行吗?.........158FAQ25:我应该如何为overlappedI/O产生一个event对象?..........159FAQ26:ReadFileEx()和WriteFileEx()的优点是什么?................163FAQ27:一个I/Ocompletionroutine何时被调用?..................163FAQ28:我如何把一个用户自定义数据传递给I/Ocompletionroutine?.165FAQ29:我如何把C++成员函数当做一个I/Ocompletionroutine?....170FAQ30:在一个高效率服务器(server)上我应该怎么进行I/O?..........172FAQ31:为什么一个I/Ocompletionports是如此特殊?..............175FAQ32:一个I/Ocompletionport上应该安排多少个线程等待?.......179FAQ33:为什么我不应该使用select()?.............................183FAQ34:volatile如何影响编译器的最优化操作?.....................198FAQ35:什么是Readers/Writerslock?.............................206FAQ36:一次应该锁住多少数据?...................................215FAQ37:我应该使用多线程版本的Crun-timelibrary吗?............220FAQ38:我如何选择一套适当的Crun-timelibrary?.................221FAQ39:我如何使用_beginthreadex()和_endthreadex()?...........224vii常见问答集(FrequentlyAskedQuestions)ixFAQ40:什么时候我应该使用_beginthreadex()而非CreateThread()?..227FAQ41:我如何使用ConsoleAPI取代stdio.h?......................240FAQ42:为什么我不应该使用_beginthread()?......................248FAQ43:我如何以一个C++成员函数当做线程起始函数?...............256FAQ44:我如何以一个成员函数当做线程起始函数?...................261FAQ45:我如何能够阻止一个线程杀掉它自己?.......................282FAQ46:CWinApp和主线程之间有什么关系?.........................290FAQ47:我如何设定AfxBeginThread()中的pThreadClass参数?.......293FAQ48:我如何对一个特定的线程调试?.............................324FAQ49:如果一个新的线程使用了我的DLL,我如何被告知?............370FAQ50:为什么我在写DLL时需要小心所谓的动态链接?...............376FAQ51:为什么我在DllMain中启动一个线程时必须特别小心?.........379FAQ52:我如何在DLL中设定一个threadlocalstorage(TLS)?.......389FAQ53:_declspec(thread)的限制是什么?..........................392FAQ54:我应该在什么时候使用多线程?.............................398FAQ55:我能够对既有程序代码进行多线程操作吗?...................406FAQ56:我可以在我的数据库应用程序中使用多线程吗?...............................411作者序1992年,我参加了第二届MicrosoftProfessionalDevelopersConference,当时,Win32首次对大量观众展示。这是一个重大的事件,其中有许多蛊魅的新技术第一次亮相。观众不断地对展示的东西喝彩。当我看到这些新技术时,我身上Unix的那一部分说“时候到了”,而Windows3.1的那一部分则是高呼“哈利路亚”。五年过去了,好几版WindowsNT问世了。我愈是深入此书,愈是了解1992年的那场盛宴之中我的了解是多么贫乏。我听过许多“睿智”的话,比如“为MDI程序的每一个窗口准备一个线程”之类,事实上根本是错误的。有些技术(诸如overlappedI/O)很明显地被曲解了。当我钻研此书时,我发现许多其他书籍和文章从头到尾描述了各式各样的Win32函数,却很少着墨在如何使用它们,或如何搭配其他函数使用。某些函数,例如MsgWaitForMultipleObjects(),是Win32程序的运转中心,却几乎没有任何范例程序正确使用过它。在我所发现的文件给了我太多的挫败之后,我决定尽可能以实务导向的方式完成此书,如此一来,你就能看到那些Win32函数一起合作的情景。这本书的读者群很广,Win16和Unix上的程序开发者欲转移到Win32,或是有经验的Win32程序开发者,都是我的对象。你会发现一些不曾看过的问答,例如“为什么_beginthreadex()真的很重要”等等。程序范例从基本层面到同步机xixii作者序制,到多线程COM和ISAPI应用程序,都有。这是一本可以让你上手实验“Win32线程”的书。我描述了基础观念,如果你需要更理论性的知识,你还得多看点其他资料。线程的大部分问题都已经被Dijkstra和Courtois那样的人在25年前就解决掉了,他们的论文直到今天还适用。如果你对那些只挑软柿子吃而故意忽略困难部分的书籍感到绝望,我希望本书能够让你绝地逢生。某些章节是经过了长时间的实验、多篇相关文章(来自杂志、期刊、MicrosoftKnowledgeBase)的阅读、众多源代码的剖析之后,萃炼而得。像“线程与Cruntime函数库以及MFC的关系”这种主题,我保证你会从中获得许多闪亮的宝石。许多程序员对于线程是既期待又怕受伤害。Unix的人嘲笑它,因为进程(process)看起来就已经不错了。Win16的人也嘲笑它,因为PeekMessage()也运作得很好嘛!我写这本书时首先认识的一个关键问题就是:如果有任何一个人在乎所谓的线程,他为的是什么?如果你开发的是服务器(server)产品,你就应该对线程深深在乎,因为I/Ocompletionports使用它。I/Ocompletionports是唯一能够搭配Win32sockets或namedpipes完成高效率I/O的方法。请你“跑”到第6章看个明白(用“走”字显得太慢了)。如果你开发的是Web产品,那么IIS(InternetInformationServer)的扩充软件也是靠多线程DLLs完成的。这种技术的背景观念散布于整本书,而第16章则告诉你如何施行那些观念。本书第一篇的程序是以C完成的,C++的分量很少。从第二篇开始我们就往C++移动了。一如我在第9章所说,C++是大势所趋,不论你是否使用MFC。如果你的C++根基不稳,我希望你特别注意一下第9章。作者序xiii谁应该读这本书凡是C/C++程序开发人员,并有Windows程序设计经验(不论是Win16或Win32),企图对线程、核心对象、overlappedI/OinWin32获得更坚实之认识者,本书就是针对你们而写的。本书谈的是API函数的使用、你会遭遇的问题,以及Windows架构对其用途的影响。读过本书之后,你将有能力分析哪里是线程可以发挥效用的地方,哪里是你应该躲闪它们的地方。几乎整本书的重点都放在产生真正可用的程序上。神秘手法以及不安全的设计已经被我排除了。Unix程序员将会发现,Win32和Unix之间有着基础观念上的差异。本书架构本书的第一篇——“上路吧,线程”,为你建立必要的基础,包括线程的启动和结束、核心对象、激发和未激发状态的意义、同步机制及其用途。有经验的Win32程序员或许可以跳过这一部分。不过第6章所讨论的主题(诸如I/Ocompletionports),是非常重要的题目,而且总的来说,其文件非常贫乏。本书的第二篇,“多线程程序设计的工具与策略”,介绍Cruntime函数库和MFC对线程的支持、如何在USER和GDI的限制之下施行多线程、如何产生一个DLL、如何对多线程程序调试。这一部分的许多信息来自于我们的研究和实际经验。本书的第三篇,“真实世界中的多线程应用程序”,谈论如何组织一个程序,使它有效支持多线程。本篇示范两个真实世界中的应用软件,第一个是个freethreadedOLEautomationserver,第二个是ISAPI程序,是个IIS(InternetInformationServer)扩充软件,示范如何和JET数据库交谈。xiv作者序关于范例程序整本书中我用了许多文本模式程序来示范观念。有些人不喜欢这种选择,但我相信一个50~100行的程序绝对比一个有着消息循环、资源文件、窗口函数……并且超过750行的Windows程序更能够集中读者的目光。读这本书你不会看到太多与用户界面相关的东西。我相信本书的范例程序以其目前的形态对你会比较有帮助。面对这些范例程序,我使用了多方的错误检验。虽然这些检验导致程序代码看起来有些杂乱,但是错误检验对于生产一个真正的应用软件很重要,对于一本书也很重要。相关阅读有两样东西是任意时候你尝试写任意Win32程序时应该要准备的。第一样东西是MicrosoftDeveloperNetwork。其光盘内含不可置信的巨量技术资料,包括MicrosoftKnowledgeBase、编译器和Win32的完整手册,以及MicrosoftSystemsJournal。第二样东西是JeffreyRichter的一本卓越书籍:AdvancedWindowsNT:TheDevelopersGuidetotheWin32APIforWindowsNT3.5andWindows95(MicrosoftPress,1995)。虽然其中遗漏了某些NT3.51的新东西,但其他方面非常有价值。译注:Jeffrey的书已出至第3版,名为AdvancedWindowsThirdEdition。它的小标题写着:forWindows95&WindowsNT4.0。目录函数索引(FunctionIndex).....................................................封面里常见问答集(FrequentlyAskedQuestions)....................................vii第一篇上路吧,线程第1章为什么要“千头万绪”.............................................................3一条曲折的路.............................................................................4与线程共枕.................................................................................7为什么最终用户也需要多线程多任务.....................................8Win32基础................................................................................10ContextSwitching.................................................................14RaceConditions(竞争条件).............................................16AtomicOperations(原子操作).........................................19线程之间如何通讯...................................................................22好消息与坏消息.......................................................................22第2章线程的第一次接触...................................................................25产生一个线程...........................................................................26使用多个线程的结果...............................................................31核心对象(KernelObjects)...............................................36线程结束代码(ExitCode).................................................40结束一个线程...........................................................................45错误处理...................................................................................48后台打印(BackgroundPrinting).....................................50成功的秘诀...............................................................................59iii目录第3章快跑与等待...............................................................................61看似闲暇却忙碌(BusyWaiting).......................................62性能监视器(PerformanceMonitor).................................66等待一个线程的结束...............................................................72叮咚:被激发的对象(SignaledObjects).......................74等待多个对象...........................................................................77在一个GUI程序中等待...........................................................85提要...........................................................................................91第4章同步控制(Synchronization)...............................................93CriticalSections(关键区域、临界区域).....................95死锁(Deadlock).................................................................102哲学家进餐问题(TheDiningPhilosophers)...............103互斥器(Mutexes)...............................................................107信号量(Semaphores).........................................................115事件(EventObjects).......................................................120从Worker线程中显示输出...................................................124InterlockedVariables.......................................................125同步机制摘要.........................................................................128第5章不要让线程成为脱缰野马.....................................................131干净地终止一个线程.............................................................132线程优先权(ThreadPriority).......................................138初始化一个线程.....................................................................144提要.........................................................................................146第6章OverlappedI/O,在你身后变戏法......................................149Win32文件操作函数..............................................................151被激发的FileHandles........................................................155被激发的Event对象.............................................................159异步过程调用(AsynchronousProcedureCalls,APCs).163对文件进行OverlappedI/O的缺点...................................171I/OCompletionPorts.........................................................172目录iii对Sockets使用OverlappedI/O........................................182提要.........................................................................................190第二篇多线程程序设计的工具与手法第7章数据一致性(DataConsistency)......................................195认识volatile关键字...........................................................196ReferentialIntegrity.......................................................200TheReaders/WritersLock.................................................205我需要锁定吗?.....................................................................214LockGranularity(锁定粒度).........................................215提要.........................................................................................216第8章使用CRun-timeLibrary.......................................................219什么是CRuntimeLibrary多线程版本.............................220选择一个多线程版本的CRuntimeLibrary......................221以CRuntimeLibrary启动线程.........................................224哪一个好:CreateThread()抑或_beginthreadex()?...227避免stdio.h..........................................................................237一个安全的多线程程序.........................................................240结束进程(Process)...........................................................248为什么你应该避免_beginthread()...................................248提要.........................................................................................251第9章使用C++.................................................................................253处理有问题的_beginthreadex()函数原型.......................253以一个C++对象启动一个线程............................................256建立比较安全的CriticalSections..................................265建立比较安全的Locks..........................................................268建立可互换(Interchangeable)的locks........................270异常情况(Exceptions)的处理.........................................274提要.........................................................................................274iv目录第10章MFC中的线程.....................................................................277在MFC中启动一个Worker线程.........................................278安全地使用AfxBeginThread()的传回值..........................282在MFC中启动一个UI线程.................................................288与MFC对象共处...................................................................293MFC的同步控制....................................................................296MFC对于MsgWaitForMultipleObjects()的支持.............300提要.......................................................................................301第11章GDI与窗口管理...................................................................303线程的消息队列...................................................................304消息如何周游列国...............................................................306GUI效率问题........................................................................311以Worker线程完成多线程版MDI程序.............................311多个上层窗口(TopLevelWindows)如何是好?.........313线程之间的通讯...................................................................314NT的影子线程(shadowthread)....................................316关于“Cancel”对话框.......................................................316锁住GDI对象.......................................................................319提要.......................................................................................319第12章调试.......................................................................................321使用WindowsNT..................................................................322有计划地对付错误...............................................................322BenchTesting.....................................................................323线程对话框...........................................................................324运转记录(Logging).........................................................325内存记号(MemoryTrails).............................................327硬件调试寄存器(HardwareDebugRegisters)...............328科学方法...............................................................................330提要.......................................................................................333目录v第13章进程之间的通讯(InterprocessCommunication).........335以消息队列权充数据转运中心...........................

相关资料推荐

  • 名称/格式
  • 下载次数
  • 资料大小

用户评论

0/200
暂无评论

资料阅读排行

该用户的其它资料

关闭

请选择举报的类型

关闭

提示

提交成功!

感谢您对爱问共享资料的支持,我们将尽快核实并处理您的举报信息。

关闭

提示

提交失败!

您的举报信息提交失败,请重试!

关闭

提示

重复举报!

亲爱的用户!感觉您对爱问共享资料的支持,请勿重复举报噢!

收藏
资料评价:

所需积分:0 立即下载
返回
顶部
举报
资料
关闭

温馨提示

感谢您对爱问共享资料的支持,精彩活动将尽快为您呈现,敬请期待!