关于InitializeCriticalSectionAndSpinCount的疑问

tomcx 2010-01-13 12:05:24
其实也不是使用中的问题,但是有些疑惑。
MSDN中提到InitializeCriticalSectionAndSpinCount函数在单处理器的情况下循环数dwspincount设定无意义,该函数工作机制和InitializeCriticalSection相同,即entercriticalsection失败后就立刻进入wait状态。

从这个函数的工作机制来说,当一个线程使用cs而发现有另一个线程正在使用时,首先不进入wait状态,而是尝试进行指定次数的循环锁等待后才进入wait状态。
个人感觉在单CPU环境下,这个工作机制对于提高性能在某些情况下也可能是有意义的,可为什么实际上这个函数却只能在多处理器环境中发挥机制?

MSDN中举了个例子:多处理器环境下,多线程并发执行争夺heap,可以让没有得到资源的线程先进入循环锁方式而不是直接wait。
可是在单处理器环境下,同样存在上述问题,线程AB争夺heap资源,结果A得到heap,在使用heap的过程中,cpu时间分配给线程B,线程B也存在循环等待还是直接wait的问题,当然从性能上说我同意直接wait,避免了频繁的上下文切换,可是感觉MS的意思是由于系统机制导致只能wait而无法循环等待。

有这个感觉主要是因为查阅了《win核心编程》中的描述如下:如果在单处理器计算机上运行时调用该函数,dwspincount参数将被忽略,它的计数始终被置为0。这是对的,因为在单处理器计算机上设置循环次数是毫无用处的,如果另一个线程正在循环运行,那么拥有资源的线程就不能放弃它。

我对这段话的理解是:在单处理器环境中循环锁一旦工作起来,处于循环等待状态的线程就无法切换到wait模式下。似乎是说操作系统在处理机制上无法实现这种机制,可是想来没有道理无法实现这个机制,不知道是不是我理解有误。

PS:最近做一个程序的优化,脑子有些浆糊,如果想法BT,请见谅。
...全文
1051 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiwssile 2010-10-16
  • 打赏
  • 举报
回复
补充下。
线程A运行关键段内代码前,必须线程B先释放。在单CPU中,本身就存在线程切换。
jiwssile 2010-10-16
  • 打赏
  • 举报
回复
在单CPU机器中,一次只能同时运行一个线程(不考虑超线程CPU)。

如果线程A进入了循环锁阶段。也就是说线程A处于运行态,而线程A想要进入临界区必须需要其他的线程(假设为线程B)释放临界区,而若线程B释放临界区,则B必须也处于运行态。

因为不可能同时运行两个线程,故,线程A的循环锁阶段毫无意义。
尘雨 2010-01-13
  • 打赏
  • 举报
回复
循环锁只是提供了一个尽快的检查是否可以获得临界区使用权的可能。但是在单处理器系统中,假设循环锁可用并生效,等于是在这种情况下不允许cpu进行线程切换。那很可能造成其他线程始终得不到足够的cpu时间。不是不可以实现,而是这样实现会造成更多问题,甚至失去了多线程,并发处理的意义。

单处理器模式下,同等优先级的线程,是分享时间片的,循环锁破坏了这种分享。如果多个线程都在做这个事情,那就是另外一个竞争条件的复杂度了。

多处理器模式下,多线程的调度,就不是简单的分享某个cpu的时间片,他有了实际意义上的并发处理。在更细的粒度上可以实现并发。因而循环锁可以更快的让线程得到某个cpu的时间片。

所以说,在单处理器模式下,循环锁用还不如不用,干脆就是0.
tomcx 2010-01-13
  • 打赏
  • 举报
回复
谢谢~

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧