我可以创建多少个CRITICAL_SECTION?

时间:2009-05-31 20:46:41

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

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

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

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

老实说,并非所有那些对象可能需要对我的应用程序是线程安全的,但关键部分是在库中的某个低级基类中,我确实需要一个他们中的几千人!

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

3 个答案:

答案 0 :(得分:9)

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

如果您发现正在引发STATUS_NO_MEMORY异常,则可以尝试仅为给定对象初始化CRITICAL_SECTION,如果它有可能在多个线程中使用的话。如果您知道某个特定对象仅用于一个线程,请设置一个标记,然后跳过对InitializeCriticalSection()EnterCriticalSection()LeaveCriticalSection()DeleteCriticalSection()的所有调用。< / p>

答案 1 :(得分:7)

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

我不知道有哪些文档说明了什么条件满足'按需',但是我怀疑它不会在进入临界区时线程阻塞之前创建。对于具有旋转计数的关键部分,可能直到旋转等待耗尽。

从经验上讲,我已经开发了一个应用程序,我知道它创建了至少60,000个实时COM对象,每个对象都与自己的CRITICAL_SECTION同步。我从来没有看到任何错误表明我已经耗尽了内核对象的供应。

答案 2 :(得分:0)

Afaik Windows上的大多数句柄/资源类型受内存或maxint限制,无论是什么先发生。 (理论上,64位maxint可能会发生)。

您在这个主题上发现的有时很容易的文本通常只与Win9x有关,后者有一定的局限性。 (总共64k内核对象)