9

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

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

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

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

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

4

3 回答 3

9

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

如果您发现STATUS_NO_MEMORY引发了异常,则可以尝试仅在CRITICAL_SECTION给定对象有可能在多个线程中使用的情况下对其进行初始化。如果您知道特定对象将仅用于一个线程,请设置一个标志,然后跳过对InitializeCriticalSection()EnterCriticalSection()LeaveCriticalSection()和的所有调用DeleteCriticalSection()

于 2009-05-31T20:53:33.427 回答
7

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

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

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

于 2009-05-31T22:29:00.270 回答
0

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

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

于 2009-06-01T14:36:18.850 回答