Concurrency Nomenclature

Started by
10 comments, last by Fruny 19 years, 6 months ago
What do I call a concurrency object that allows one thread to open it at a time but can allow nested opens / closes by that same thread. eg: thread 1 opens BLARG thread 2 blocks waiting for BLARG thread 1 opens BLARG (2 opens) thread 1 closes BLARG thread 1 closes BLARG thread 2 wakes and enters BLARG This isn't like a semaphore because it allows only one thread, but it isn't a mutex either because it counts. Why? because I have critical sections of code and the user of the critical sections is allowed to open the mutex to encapsulate all critical sections inside one critical section. eg: user opens BLARG user calls external BLARG-critical function 1 user calls external BLARG-critical function 2 user calls external BLARG-critical function 3 user closes BLARG The external functions open and close BLARG, and are not written by the user but by me. Any idea what I should call this, or whether I should use something else?
Advertisement
You use critical section for that.

thread 1 enters CriticalSection
thread 1 opens BLARG
thread 2 waits on CriticalSection
thread 1 closes BLARG
thread 1 opens BLARG
thread 1 closes BLARG
thread 1 opens BLARG
thread 1 closes BLARG
thread 1 leaves CriticalSection
thread 2 continues.

You can encapsulate this behaviour in a monitor.

(I edited soon after I posted it in hopes that the thread would not be affected. Unfortunately, it was. Apologies for that.)

[Edited by - flangazor on October 8, 2004 6:43:02 AM]
That would be called a deadlock if it were a mutex. I said that the object allows nested opens.

EDIT: Message this referred to has disappeared.

[Edited by - Krylloan on October 8, 2004 5:44:32 AM]
On windows, mutex objects allow multiple opens:

Quote:From MSDN
The thread that owns a mutex can specify the same mutex in repeated wait function calls without blocking its execution.
Is that the case with linux also?

I'm assuming that if you open the windows mutex multiple times and close it once it is immediately closed, eg it doesn't count. Is that right?

Thanks

Thanks flangzor, but the problem I have is that the user doesn't need to perform the encapsulation.

this is also ok:
user calls external BLARG-critical function 1
user opens BLARG
user calls external BLARG-critical function 1
user closes BLARG

external BLARG-critical function 1:
external opens BLARG
external performs operations on BLARG-protected variables
external closes BLARG

I realise I am going to have to create this functionality using a supported concurrency object. It is quite easy to enforce the above using 2 mutexes, although it's not wonderfully efficient unless the mutexes are superfast.
Under linux, using pthreads, there's a parameter you pass that tells the system whether you want the 'recusive' behaviour or not.

On windows, every call to WaitForSingleObject requires a corresponding call to ReleaseMutex.

If by "open" you were talking about the call to CreateMutex, then each call to CreateMutex returns a different handle (to the same object, assuming you're passing in the same name) and so you need to call CloseHandle on each one to close the actual underlying object.
Thanks dean. Looks like regular mutexes can do what I require already in both Win and Nix.
Given the way that your original post was written, I thought you might be trying to write multiple transactions to a database in one thread before another thread can access the db. By 'open' I thought you might mean 'open a write context.'

With regards to speed of Mutexes, you may like to look up Spinlocks.
Quote:Original post by Krylloan
[...]I realise I am going to have to create this functionality using a supported concurrency object. It is quite easy to enforce the above using 2 mutexes, although it's not wonderfully efficient unless the mutexes are superfast.
If you only need these locks to work within a single process in windows, a CriticalSection would be the way to go. They allow nesting and DO count so you need one 'release' for each 'acquire'. With reguards to speed - I had a class with tons of functions being called by several threads (some of the threads were multimedia timers that needed 1-ms accuracy), and putting a critical section around each function in the object didn't slow things down at all.

You just need to be smart about it. For example, instead of doing
Func1(){  Func2ThatAcquiresAndReleases();  Acquire();  //DoStuff  Release();}
you'd want to do:
Func1(){  Acquire();  Func2ThatAcquiresAndReleases();  //DoStuff  Release();}
because the second version only has to wait for the criticalsection a single time, while the first version has to wait twice.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

This topic is closed to new replies.

Advertisement