【问题标题】:How many CRITICAL_SECTIONs can I create?我可以创建多少个 CRITICAL_SECTION?
【发布时间】:2010-10-30 06:56:45
【问题描述】:

我可以初始化和使用的关键部分的数量是否有限制?

我的应用创建了许多(几千个)需要线程安全的对象。如果我在每个中都有一个关键部分,那会占用太多资源吗?

我认为因为我需要声明自己的 CRITICAL_SECTION 对象,所以我不会像使用 Win32 Mutex 或 Event 那样浪费内核资源?但我只是有一个挥之不去的疑问......?

老实说,对于我的应用程序来说,并不是所有这些对象需要是线程安全的,但关键部分位于库中的某个低级基类中,我确实需要一个几千个!

我可能有机会修改这个库,所以我想知道是否有任何方法可以仅在我检测到对象正在从不同的线程使用时才懒惰地创建(然后从那时起使用)关键部分创建它的那个?或者这就是 Windows 会为我做的?

【问题讨论】:

    标签: c++ multithreading winapi windows-xp thread-safety


    【解决方案1】:

    您可以声明的CRITICAL_SECTION结构的数量没有限制——它们只是最低级别的 POD 数据结构。您可以使用InitializeCriticalSection()初始化的数量可能有一些限制。根据文档,它可能会在 Windows 2000/XP/Server 2003 上引发STATUS_NO_MEMORY 异常,但显然它可以保证在 Vista 上成功。在您初始化它们之前,它们不会占用任何内核资源(如果它们占用了任何资源)。

    如果您发现引发了STATUS_NO_MEMORY 异常,您可以尝试只为给定对象初始化CRITICAL_SECTION,前提是它有可能在多个线程中使用。如果您知道某个特定对象只能用于一个线程,请设置一个标志,然后跳过对InitializeCriticalSection()EnterCriticalSection()LeaveCriticalSection()DeleteCriticalSection() 的所有调用。

    【讨论】:

    • 谢谢亚当。我也想将你的答案设置为接受的答案,但我一次只能设置一个,而 Matthew 的 60,000 个 COM 对象的经验证据给了我温暖的模糊感觉!
    • @SteveFolly 我听到有人在实践中使用 60,000 个关键部分时也有同样的反应。
    【解决方案2】:

    如果您仔细阅读IntializeCriticalSectionWithSpinCount() 的文档,很明显每个临界区都由一个事件对象支持,尽管临界区的 API 将它们视为不透明的结构。此外,对 dwSpinCount 参数的“Windows 2000”注释指出事件对象是“按需分配的”。

    我不知道有任何文档说明什么条件满足“按需”,但我怀疑它是在线程进入临界区时阻塞之前不会创建的。对于具有自旋计数的临界区,可能要等到自旋等待耗尽。

    根据经验,我曾开发过一个应用程序,据我所知该应用程序至少创建了 60,000 个活动 COM 对象,每个对象都与自己的 CRITICAL_SECTION 同步。我从未见过任何表明我已用尽内核对象供应的错误。

    【讨论】:

      【解决方案3】:

      Afaik Windows 上的大多数句柄/资源类型都受到内存或 maxint 的限制,无论哪个先出现。 (我猜理论上可能会发生 64 位 maxint)。

      你在这个主题上找到的有时乏味的文本通常只与 Win9x 相关,它有一些限制。 (总共 64k 内核对象)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-25
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多