学习用互斥对象实现线程同步

 前段时间要做个多线程数据共享的例子。多线程之间用过不少,数据同步,是第一次做。

之前看书的时候看到很多这方面的说明,感觉很复杂,一直没去深入。这次要做这个应用了,遇上不少问题。

一开始就是看不懂网上的教程,看了之后,发现人家讲了很多,自己看了,似乎看懂了又没看懂。

嫌麻烦就尝试用一个全局变量来做“忙标志”,要操作数据的线程先把标志置“忙”,操作完之后恢复为“闲”。其它线程看到忙标志就暂停,空跑。

在windows2003写完代码后运气起来“感觉没问题”,而在XP系统下一下子就崩溃了。

多线程的代码调试下来非常麻烦,我也是不懂在delphi环境下该如何调。

 

后来经过一番摸索,发现用互斥对象来做相对简单些,看了教程加自己摸索了一阵,终于弄懂了,但也不知道懂得对不对。望大家指正。

 

举个例子而言,

有两个子线程,都是要对同一个全局数据BUFFER进行操作(有写有读),应该怎样避免数据访问冲突呢?

 

1.全局变量声明。

const
  MUTEX_DATA : string = 'P1P2P3C1C2DATA';

var

  hMutexData: THandle = INVALID_HANDLE_VALUE;

 

2.在你的主线程(系统为程序默认创建的第一个线程)创建子线程之前,初始化互斥对象。

hMutexData := CreateMutex(nil, False, PChar(MUTEX_DATA));

该函数的使用请参阅其它资料,注意第二个参数要为False,表示创建的时候不“打开”这个互斥量。

 

3.在各个线程要操作全局数据BUFFER(或写或读)前等待,请求互斥量。

WaitForSingleObject(hMutexData, INFINITE);

INFINITE表示无限等待。如果当前互斥量处于“空闲”状态,则把互斥对象抢占过来,然后往下执行下面的代码。

如果互斥量处于“非空闲”状态,则一直等待到“空闲”才往下执行代码。该方式不占用CPU时间。好像是跟Windows事件机制有关。

把互斥对象抢占过来之后,别的线程就无法取得互斥对象,要等你当前这段代码执行完毕。

 

4.在主线程退出前,释放互斥对象。

ReleaseMutex(hMutexData);

 

 

说起来,这个过程跟我一开始想的拿个全局变量来做“忙标志”的原理很接近,可为什么我那个方法不行。。。可能没处理好吧。。。懒,没深究。。。

 

要补充两点:

1.上面讲的是同步一个全局数据,其实如果多个线程访问同一个窗体或同一个控件时,也可以使用这样的方法。它们也是全局数据的一种。

2.上面的第三步加“等待互斥对象”的代码究竟加在哪里是有讲究的。

同一个线程最好只等待一个互斥对象(可以有多个互斥对象)。如果在一个线程中多次调用WaitForSingleObject(hMutexData, INFINITE),那么你就要处理好代码执行顺序的问题,否则很容易死锁。宁愿多创建几个互斥对象,如不同的代码不同的互斥对象。

如:

WaitForSingleObject(hMutexData111, INFINITE);

WaitForSingleObject(hMutexData222, INFINITE);

WaitForSingleObject(hMutexData333, INFINITE);

 

互斥对象用起来其实很简单。就是没被点透。

希望这篇文章能帮到你。如果我的理解,用法有问题,也希望你能指正一下,不胜感激。

 

 

原创

温校宏

2009/11/15

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值