Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many CRITICAL_SECTIONs can I create?

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?

like image 219
Steve Folly Avatar asked May 31 '09 20:05

Steve Folly


2 Answers

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().

like image 70
Adam Rosenfield Avatar answered Oct 19 '22 23:10

Adam Rosenfield


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.

like image 45
Matthew Xavier Avatar answered Oct 19 '22 23:10

Matthew Xavier