按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
是我必须警告你,多线程程序的设计成功关键并不在此。如果你的每一个执行线程都非常独
立,彼此没有干联,也就罢了。但如果许多个执行线程互有关联呢?有经验的人说多线程程
式设计有多复杂多困难,他们说的并不是执行线程本身,而是指执行线程与执行线程之间的同
步控制。
原因在于,没有人能够预期执行线程的被执行。在一个合作型多任务系统中(例如Windows
3。x),操作系统必须得到程序的允许才能够改变执行线程。但是在强制性多任务系统中(如
Win95 或WinNT ),控制权被排程器强制移转,也因此两个执行线程之间的执行次序变得
不可预期。这不可预期性造成了所谓的race conditions 。
假设你正在一个文件服务器中编辑一串电话号码。文件打开来内容如下:
Charley 572…7993
Graffie 573…3976
Dennis 571…4219
763
…………………………………………………………Page 826……………………………………………………………
第篇 深入 MFC 程式設計
现在你打算为Sue 加上一笔新资料。正当你输入Sue 电话号码的时候,另一个人也打
开文件并输入另一笔有关于Jason 的资料。最后你们两人也都做了存盘动作。谁的资料
会留下来?答案是比较晚存盘的那个人,而前一个人的输入会被覆盖掉。这两个人面临
的就是race condition 。
再举一个例子。你的程序产生两个执行线程,A和B。执行线程B的任务是设定全域变量X。
执行线程A则要去读取X。假设执行线程B先完成其工作,设定了X,然后执行线程A才执行,
读取X,这是一种好的情况,如图14…6a。但如果执行线程A先执行起来并读取全域变量
X,它会读到一个不适当的值,因为执行线程B还没有完成其工作并设定适当的X。如图
14…6b。这也是race condition 。
另一种执行线程所造成的可能问题是:死结(deadlock )。图14…7 可以说明这种情况。
图14…6a race condition (good)
执行线程A 执行线程B
Good
2
全域变量X
3 1
执行线程B先完成其工作,设定了全域变量X,然后执行线程A才读取X。
?? 表示执行次序
??
图 14…6a race condition (good)
764
…………………………………………………………Page 827……………………………………………………………
14 MFC
第 章 多緒程式設計
执行线程A 执行线程B
Bad
2
全域变量X
1 3
执行线程A先执行并读取全域变量X,然后执行线程B才设定X。太迟了。
?? 表示执行次序
??
???? 圖 14…6b race condition (bad )
NULL 执行线程A 执行线程B
NULL
执行线程A在此等待
执行线程B在此等待
全域变量global1
全域变量global2
从NULL 改变为合 global 1
法的值 NULL 从NULL 改变为合
法的值
NULL
执行线程A在此提供
执行线程B在此提供
global 2
全域变量global2 全域变量global1
的值
的值
图14…7 死结 (deadlock)
765
…………………………………………………………Page 828……………………………………………………………
第篇 深入 MFC 程式設計
要解决这些问题,必须有办法协调各个执行线程的执行次序,让某个线程等待某个线程。
Windows 系统提供四种同步化机制,帮助程序进行这种工作:
1。 Critical Section (关键区域)
2。 Semaphore (号志)
3。 Event (事件)
4。 Mutex (Mutual Exclusive ,互斥器)
MFC 也提供了四个对应的类别:
CObject
CObject
CSyncObject
CSyncObject
CCriticalSection
CCriticalSection
CEvent
CEvent
CMutex
CMutex
CSemaphore
CSemaphore
一想到本书的厚度,我就打消介绍