65.9K
CodeProject 正在变化。 阅读更多。
Home

一个在Windows 9x上工作的TryEnterCriticalSection

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (6投票s)

2002 年 9 月 21 日

2分钟阅读

viewsIcon

81473

downloadIcon

1211

TryEnterCriticalSection 是一个用于确定某些受保护资源是否繁忙的有用工具,但它仅在 NT 平台上可用……直到现在。

引言

不久前,我需要编写一个需要多个线程的应用程序。该应用程序中的一个线程将负责一些共享资源,而其他线程必须请求权限才能临时独占访问该共享资源。 我知道该资源不需要在多个进程之间共享,因此我想避免使用昂贵的内核对象。 我决定使用临界区来保护资源,多个使用线程将调用 ::TryEnterCriticalSection() API 来请求许可,如果获得许可,则可以独占访问共享资源。 此解决方案的唯一问题是 ::TryEnterCriticalSection() 仅在 NT 平台上可用,而我需要支持 9x。

解决方案

这个问题涌入了我的脑海。 我考虑的第一个解决方案是使用互斥对象,其中消耗线程将调用 ::WaitForSingleObject() API,将 0 传递给函数的第二个参数(表示该函数应该尝试获取互斥体,但不要等待它),并检查返回值 WAIT_OBJECT_0。 此解决方案的问题在于它需要使用互斥内核对象,并且从用户模式切换到内核模式非常昂贵。 我决定放弃该解决方案。 在考虑了其他一些可能性之后,我决定编写我自己的临界区类,该类允许“尝试进入”逻辑。

CTryEnterCS 类

CTryEnterCS 是该努力的成果。 实际上,它非常易于使用,因为该类中只有两个公共方法。 它 100% 在用户模式下运行,利用 ::InterlockedExchange()::GetCurrentThreadId() API。 以下是公共方法的说明

bool TryEnter()

如果当前线程尚未拥有临界区,则此方法锁定当前线程的临界区。 如果当前线程已经拥有临界区(重入),则允许当前线程通过。 如果已进入临界区,则返回 true;否则返回 false
bool Leave()
如果当前线程已进入临界区(使用 TryEnter()),则此方法释放(离开)对临界区的拥有权。 如果成功,则返回 true;如果失败或当前线程未拥有临界区,则返回 false

历史

   
  •  
  • 2002年9月21日  初始版本。
       
  •  
  • 2002年9月25日  TryEnter 现在引用了来自同一线程的多个条目; Leave 递减计数,当计数为零时释放锁。
    © . All rights reserved.