按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
afx_msg void OnStopthread();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg LONG OnThreadended();
11。 在资源编辑器中删除 “线程”主菜单中的 “停止线程”菜单选
项。
现在编译并运行Thread程序的新版本。当运行这个程序后,主窗口首
先出现。选择 “线程”主菜单中的 “启动线程”菜单选项,首先弹出
如图12。4所示的消息框显示当前受保护的数组的值。每次当你单击消
息框的 “确定”按钮,一个新的消息框又出现。这种消息框要出现20
次。在消息框中列出的数组的值取决于单击消息框的 “确定”按钮以
销毁消息框所花的时间,因为第一个线程每一秒更新一次数组中的数
据。
图12。 4 读取数据对话框
如果没有线程同步,则在消息框中出现的数字将不会相同。
如果仔细检查源代码,你会发现第一个线程WriteThreadProc()在一
个循环类十次调用CCountArray类的成员函数SetArray()。每一次
SetArray()函数将criticalSection给这个线程,修改受保护的数组
的值,然后又释放对criticalSection的所有权。注意函数Sleep(),
它将这个线程挂起1000毫秒。
…………………………………………………………Page 654……………………………………………………………
第二个线程ReadThreadProc()为了构造一个显示数组元素的字符串也
在访问criticalSection。但是如果WriteThreadProc()正在用更新数
组中元素的值,ReadThreadProc()必须等待。反之也是对的,即
WriteThreadProc()不能够访问受保护的数据直到它重新从
ReadThreadProc()得到对criticalSection的所有权。
如果你希望测试一下criticalSection是否在起作用,把SetArray()
函数最后的criticalSection。Unlock()删除。重新编译并运行该程
序,这次没有消息框出现。因为WriteThreadProc()完全占有了
criticalSection,这将导致系统一致将ReadThreadProc()挂起,直
到你退出这个程序。
(2) 使用Mutex (互斥对象)
互斥对象有点象critical section,但有些复杂,因为它不仅允许同
一程序的线程之间,而且允许不同程序的线程之间共享资源。尽管在
不同程序之间的线程同步超出了本章的范围,但是你可以通过替换
critical section获得使用互斥对象的经验。
下面是CCountArray2类的头文件。除了名称和互斥对象外,这个文件
和原来的CCountArray完全相同。
#include 〃afxmt。h〃
class CCountArray2
{
private:
int array'10';
CMutex mutex;
public:
CCountArray2() {};
~CCountArray2() {};
void SetArray(int value);
void GetArray(int dstArray'10');
};
…………………………………………………………Page 655……………………………………………………………
下面是CCountArray2的执行文件,正如你所看到的,尽管互斥对象和
critical section提供相同的服务,但是二者使用起来还是有很多不
同的。
#include 〃stdafx。h〃
#include 〃CountArray2。h〃
void CCountArray2::SetArray(int value)
{
CSingleLock singleLock(&mutex);
singleLock。Lock();
for (int x=0; x