【问题标题】:OK to copy a CRITICAL_SECTION?可以复制 CRITICAL_SECTION 吗?
【发布时间】:2010-07-16 22:25:25
【问题描述】:

可以使用 CRITICAL_SECTION 变量来实现互斥。

我的问题是:CRITICAL_SECTION 是否支持复制?如果我按值将一个传递给另一个线程,我可以确定互斥会起作用吗?

如果答案是“你不能那样做”,我不会感到惊讶,但最好能得到某种官方确认。无论哪种方式,我都无法在文档中找到声明。

【问题讨论】:

    标签: c winapi synchronization


    【解决方案1】:

    没有。无法复制 CRITICAL_SECTIONMSDN states this explicitly:

    不能移动或复制临界区对象。

    【讨论】:

      【解决方案2】:

      快速搜索标题会发现该结构是在winnt.h 中定义的,而这个定义显然表明复制该结构是行不通的。

      typedef struct _RTL_CRITICAL_SECTION {
          PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
      
          //
          //  The following three fields control entering and exiting the critical
          //  section for the resource
          //
      
          LONG LockCount;
          LONG RecursionCount;
          HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
          HANDLE LockSemaphore;
          ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
      } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
      

      也就是说,我不知道为什么这些内部计数器存储在用户空间结构中,即如果程序修改这些会发生什么?

      【讨论】:

      • 文档明确指出不能修改CRITICAL_SECTION 的内容:“进程也不能修改对象,但必须将其视为逻辑不透明。”
      • 这就是我提出这个问题的原因。 “不能”是什么意思?用户程序可以操作除句柄之外的任何内容并不常见。
      • 如果 API 说 API 的使用者必须不做某事,这意味着“如果你这样做,所有的赌注都没有了。”
      • 而关键部分的目的是 FAST。这意味着它不能花时间进入内核并离开进入。如果您想要一个提供与临界区相似语义的同步对象,请使用互斥对象。这样您就不必担心所有这些内部细节都会暴露给应用程序。当然,您的应用程序会比关键部分慢很多,但这就是您为架构纯度付出的代价。
      猜你喜欢
      • 2010-10-30
      • 1970-01-01
      • 2011-05-24
      • 2014-12-13
      • 2012-08-25
      • 2011-12-31
      • 2012-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多