线程同步--关键代码段(三)

前面讲述了如何使用关键代码段。

但是关键代码段还有一些不为人知的秘密,也是多数程序员忽略的东西,特别是在多核cpu上面,我们必须知道的东西。

下面是《windows核心编程》这本书里面的一段话。插一句话,搞windows编程的此书必看,本人正在读中,感觉就是醍醐灌顶!

当线程试图进入另一个线程拥有的关键代码段时,调用线程就立即被置于等待状态。这意
味着该线程必须从用户方式转入内核方式(大约1 0 0 0个C P U周期)。这种转换是要付出很大代
价的。在多处理器计算机上,当前拥有资源的线程可以在不同的处理器上运行,并且能够很快
放弃对资源的控制。实际上拥有资源的线程可以在另一个线程完成转入内核方式之前释放资源。
如果出现这种情况,就会浪费许多C P U时间。

我们知道了,为什么要了解多核cpu关键代码段的秘密。

为了提高关键代码段的运行性能, M i c r o s o f t将循环锁纳入了这些代码段。因此,当
E n t e r C r i t i c a l S e c t i o n函数被调用时,它就使用循环锁进行循环,以便设法多次取得该资源。只
有当为了取得该资源的每次试图都失败时,该线程才转入内核方式,以便进入等待状态。

 

我们只需要将

InitializeCriticalSection(&cs[0]);

改为

InitializeCriticalSectionAndSpinCount( &cs[0] , 4000 );

就可以了 。

第一个参数不变,第二个参数为请求次数上限(范围是 0 ~  0x00FFFFFF),若达到了上限还是没有获得资源的时候,线程这个时候才从  用户方式进入内核方式(这就是浪费了CPU时间)。

如果我们想改变次数可以用下面函数

SetCriticalSectionSpinCount( &cs[0] , 6000 );

 

 

以上红色字体均是来自于windows核心编程。

 

你可能感兴趣的:(线程同步--关键代码段(三))