![]() ![]() |
|
Win32下两种用于C++的线程同步类(上) | |
作者:佚名 文章来源:不详 点击数 更新时间:2008/3/7 12:10:48 文章录入:杜斌 责任编辑:杜斌 | |
|
|
这里我要说的是两种用于C++的多线程同步类,通过对这两种类的使用就可以方便的实现对变量或代码段的加锁控制,从而防止多线程对变量不正确的操作。 所谓加锁,就是说当我们要访问某关键变量之前,都需要首先获得允许才能继续,如果未获得允许则只有等待。一个关键变量拥有一把锁,一个线程必须先得到这把锁(其实称为钥匙可能更形象)才可以访问这个变量,而当某个变量持有这把锁的时候,其他线程就不能重复的得到它,只有等持有锁的线程把锁归还以后其他线程才有可能得到它。之所以这样做,就是为了防止一个线程读取某对象途中另一线程对它进行了修改,或两线程同时对一变量进行修改,例如: // 全局: struct MyStruct ... { int a, b; } ; MyStruct s; // 线程1: int a = s.a; int b = s.b; // 线程2: s.a ++ ; s.b -- ; 如果实际的执行顺序就是上述书写的顺序那到没有什么,但如果线程2的执行打断了线程1,变为如下顺序: int a = s.a; //线程1 s.a++; //线程2 s.b++; //线程2 int b = s.b; //线程1 那么这时线程1读出来的a和b就会有问题了,因为a是在修改前读的,而b是在修改后读的,这样读出来的是不完整的数据,会对程序带来不可预料的后果。天知道两个程的调度顺序是什么样的。为了防止这种情况的出现,需要对变量s加锁,也就是当线程1得到锁以后就可以放心的访问s,这时如果线程2要修改s,只有等线程1访问完成以后将锁释放才可以,从而保证了上述两线程交叉访问变量的情况不会出现。 使用Win32提供的临界区可以方便的实现这种锁: // 全局: CRITICAL_SECTION cs; InitializeCriticalSection( & cs); // 线程1: EnterCriticalSection( & cs); int a = s.a; int b = s.b; LeaveCriticalSection( & cs); // 线程2: EnterCriticalSection( & cs); s.a ++ ; s.b -- ; LeaveCriticalSection( & cs); // 最后: DeleteCriticalSection( & cs); 代码中的临界区变量(cs)就可以看作是变量s的锁,当函数EnterCriticalSection返回时,当前线程就获得了这把锁,之后就是对变量的访问了。访问完成后,调用LeaveCriticalSection表示释放这把锁,允许其他线程继续使用它。 |
|
![]() ![]() |