Let's say variable A is modified inside the body of the OpenMP critical section, and also assume that this variable A is also modified outside the critical section without critical construct but still inside the parallel region. I just wanted to know if critical section would protect update to this variable (which might happen outside) or not while one of the threads are inside the critical region? Thanks.
No, the critical section only 'protects' updates made inside the section. Any update to the 'protected' variables outside the critical section leaves those variable unprotected. And don't forget, the critical section means that only one thread at a time executes the code that it (the critical section) encloses.
This seems entirely obvious so makes me wonder why you ask the question and what, perhaps, you are trying to achieve.
Related
I want to use a variable across multiple threads. To safeguard simultaneous access to that variable, i would like to add a mutex for that variable. But mutex and critical section better suited for piece of code. In case of a variable, it looked ugly to place lock and unlock code everywhere the variable is used. Is there any other simpler way than mutex and critical section?
If it's one variable that you want to protect then use std::atomic (if you are using c++11) or boost::atomic if not.
If it's multiple shared variables in the critical section then you'd need to be careful of cache coherency issues. So I'd use mutexes in that case arround the critical section
Some code must not run genuinely parallel: either not inside a OpenMP parallel region or within a OpenMP single block. How can I assert that the code is not running genuinely parallel (ignoring for the time being the complications arising from nested parallelism)?
I don't think there's a way to do exactly what you want.
However, you could use the "critical" construct to ensure a code section is executed only by one thread at a time, and then set some flag to prevent it to be run by another thread, if it should be run only once.
I use to use critical section (in c++) to block theads execution whilel accessing shared data, but as to work them must need to wait until data is not used before blocking, maybe it's better to use them in main or thread.
Then if I want my main program to have priority and not be blocked must I use critical sections inside it to block other thread or the contrary ?
You seem to have rather a misconception over what critical sections are and how they work.
Speaking generically, a critical section (CS) is a piece of code that needs to run "exclusively" -- i.e., you need to ensure that only one thread is executing that piece of code at any given time.
As the term is used in most environments, a CS is really a mutex -- a mutual exclusion semaphore (aka binary semaphore). It's a data structure (and set of functions) you use to ensure that a section of code gets executed exclusively (rather than referring to the code itself).
In any case, a CS only makes sense at all when/if you have some code that will execute in more than one thread, and you need to ensure that it only ever executes in one thread at any given time. This is typically when you have some shared data that could and would be corrupted if more than one thread tried to manipulate it at one time. When/if that arises, you need to "use" the critical section for every thread that manipulates that data to assure that the shared data isn't corrupted.
Assuring that a particular thread remains responsive is a whole separate question. In most cases, this means using a queue (for one possibility) to allow the thread to "hand off" a task to some other thread quickly, with minimal contention (i.e., instead of using a CS for the duration of processing the data, the CS only lasts long enough to put a data structure into a queue, and some other thread takes the processing from there).
You cannot say "I am using critical section in thread A but not in thread B". Critical section is a piece of code that accesses shared resource. When this code is executed from two threads that run in parallel, shared resource might get corrupted so therefore you need to synchronise access to it: you need to use some of synchronisation objects (mutexes, semaphores, events...depending on the platform and API you are using). ThreadA locks the critical section so ThreadB needs to wait till ThreadA releases it.
If you want your main thread to block (wait) less than working thread, set working thread priority to be lower than priority of the main thread.
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.
Afaik most handle/resource types on Windows are limited by memory or maxint, whatever comes first. (in theory on 64-bit maxint could happen I guess).
The sometimes weasily texts that you find on this subject usually are relevant only to Win9x, which had some limitations. (64k kernel objects in total)
So App Verifier is throwing this exception. From what I gather, the text of this message is a little misleading. The problem appears to be that the the critical section was created by a thread that is being destroyed before the critical section is destroyed.
It's a relatively simple fix but does anyone know what the ramifications are for having a thread other than the creating one destroy the crticial section? How dangerous is it? Is the concern only that the critical section handle will "leak" or is there a more insidious side-effect?
Some other info:
App written in C++ (on Windows, of course)
Critical section created with InitializeCriticalSelection
Critical section is eventually deleted with DeleteCriticalSection
I believe you are correct on the interpretation of the message. The only reference I can find is as follows. The stack trace is a good clue as the author suggests
http://jpassing.wordpress.com/2008/02/18/application-verifier-thread-cannot-own-a-critical-section/
I dug around for a bit and cannot find any specific reason why you cannot create and delete a critical section on different threads. However I do wonder why it is that you want to do so? It seems like best practice to have one thread own a critical section so to speak. Handing off the critical section between threads introduces another means of communication and potential error (can be done, just more fun).
Seems accepted answer talks about creation of critical section, which is not what this message is about. Eran's answer covered the real cause of the message, but here it is in TL;DR terms:
Application verifier detected a thread, that acquired a critical section lock, is attempting to exit while the section is still locked
It is not complaining that thread created critical section and is now terminating. This has nothing to do with who creates and destroys the section. It is complaining, and very legitimately, that the thread owns the lock on that critical section and terminating. They could've made the wording of that message so much clearer.
As opposed to beasts such as COM objects, critical sections life cycle is not bound to a certain thread. Critical sections are constructed in two stages: upon creation, they are merely made of a few structures. Upon contention of two or more threads, a kernel mutex is created to handle the synchronization properly. Both the structures and the mutex can be created, accessed and destructed by any thread, be it the one that created the critical section or not.
To answer your questions, the above means you should have no problems creating the CS in one thread and destroying it in another. This might, however, imply some problem with the design. If you're not doing that already, consider wrapping the CS with a class that will initialize the CS in its constructor, and destroy it in its destructor (MFC's CCriticalSection does that). Then, have the wrapper created on a higher scope than the one that uses it (global, static class member, whatever). Should make the creation and cleanup much easier.
And lastly, regarding the error message itself - is it possible the thread that is being deleted has entered the CS without having the chance to leave it (due to an exception or so)? If that is the case, you got a weird looking message that points to a real problem.