Is there a limit to the number of critical sections I can initialize and use?
My app creates a number of (a couple of thousand) objects that need to be thread-safe. If I have a critical section within each, will that use up too many resources?
I thought that because I need to declare my own CRITICAL_SECTION object, I don't waste kernel resources like I would with a Win32 Mutex or Event? But I just have a nagging doubt...?
To be honest, not all those objects probably need to be thread-safe for my application, but the critical section is in some low-level base class in a library, and I do need a couple of thousand of them!
I may have the opportunity to modify this library, so I was wondering if there is any way to lazily create (and then use from then on) the critical section only when I detect the object is being used from a different thread to the one it was created in? Or is this what Windows would do for me?
There's no limit to the number of CRITICAL_SECTION
structures that you can declare -- they're just POD data structures at the lowest level. There may be some limit to the number that you can initialize with InitializeCriticalSection()
. According to the documentation, it might raise a STATUS_NO_MEMORY
exception on Windows 2000/XP/Server 2003, but apparently it's guaranteed to succeed on Vista. They don't occupy any kernel resources until you initialize them (if they take any at all).
If you find that the STATUS_NO_MEMORY
exception is being raised, you can try only initializing the CRITICAL_SECTION
for a given object if there's a chance it could be used in a multiple threads. If you know a particular object will only be used with one thread, set a flag, and then skip all calls to InitializeCriticalSection()
, EnterCriticalSection()
, LeaveCriticalSection()
, and DeleteCriticalSection()
.
If you read carefully the documentation for IntializeCriticalSectionWithSpinCount(), it is clear that each critical section is backed by an Event object, although the API for critical sections treats them as opaque structures. Additionally, the 'Windows 2000' comment on the dwSpinCount parameter states that the event object is "allocated on demand."
I do not know of any documentation that says what conditions satisfy 'on demand,' but I would suspect that it is not created until a thread blocks while entering the critical section. For critical sections with a spin count, it may not be until the spin wait is exhausted.
Empirically speaking, I have worked on an application that I know to have created at least 60,000 live COM objects, each of which synchronizes itself with its own CRITICAL_SECTION. I have never seen any errors that suggested I had exhausted the supply of kernel objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With