Hardwired's Named Critical Section and Named Spin Lock






1.55/5 (9 votes)
Feb 23, 2005
2 min read

25700

284
Named critical section and named spin lock - you may find it useful for debugging complex applications.
Introduction
Working with critical section is not quite an easy task. Of course, if you have just two threads and one critical section, it's alright. But if you have about 10 threads, and you have to synchronize the use of about 20-30 variables then you will probably have problems. A very useful tool used is ProcessExplorer from Sysinternals. But it doesn't tell you a lot about the Critical Section object. So, I needed a way to trace all the critical sections, when they get locked/unlocked, and by whom. That is all about it.
Using the code
To use these classes, you got to have the basics about CCriticalSection
and CSingleLock
. If you don't, come back when you read all about it from MSDN. This works both for /DEBUG mode and /RELEASE mode. But only in /DEBUG mode you'll be able to trace all the Critical Section "activity". In /RELEASE mode you will not get any debug messages. Still, if you wish to see them, then edit debugtrace.cpp and debugtrace.h files and remove all the #ifndef
and #endif
lines.
First add debugtrace.h, debugtrace.cpp, spinlock.h, spinlock.cpp, namedcriticalsection.h and namedcriticalsection.cpp files to your project and of course #include "namedcriticalsection.h"
where needed.
To use CNamedCriticalSection
, it's very easy, just follow the following steps:
// // MyClass.h // #include "namedcriticalsection.h" class MyClass { CNamedCriticalSection Section; public: MyClass(); ~MyClass(); void SomeMethod(void); ... };
// // MyClass.cpp // #include "myclass.h" MyClass::MyClass() : Section( "MyClass" ) // the critical section object should have // the same name as the class, but you can // set it to whatever you want { ... } MyClass::~MyClass() { ... } // // let's assume this gets executed only by one single thread // void MyClass::SomeMethod(void) { CSpinLock Spin( &Section, "MyClass::SomeMethod" ); if( Spin.Lock() ) { // // locked section; this is where you operate with // protected data // ... Spin.Unlock(); } }
OK. So, the class has a member function which locks the section and gets exclusive rights to operate with some data. We also assumed that the MyClass::SomeFunction()
gets executed only by one single thread, let's say the main thread of the process.
Let's say that the application starts another thread which wants to use the same data as the one MyClass::SomeFunction()
locks. This means that we have to wait for the critical section to get unlocked. Once it gets unlocked by the main thread, this new thread locks it. Please, also read the comments in the code sample below:
// // Thread function - started with AfxThreadBegin(...), for example // UINT SomeThread( LPVOID lParam ) { MyClass *pmy = NULL; if( NULL == ( pmy = (MyClass*)lParam ) ) return 0; // // create the spinlock // we'll use different name for spin, so we'll know that the section // is locked by the thread function // CSpinLock Spin( &(pmy->Section), "SomeThread" ); // // try to lock the section // this actualy waits infinitely till the other thread unlocks the section // if( Spin.Lock() ) { // // locked section; this is where you operate with // protected data // ... // // finished, so let's unlock the section because the other // thread waits for it. If not, you'll probably get a deadlock!!! // Spin.Unlock(); } ... return 1; }
That's all! It's very simple (I think:)), but I am sure you'll find it useful. It made me find a lot of bugs.
One more thing: If your application already has a lot of source-code you might think that it is really hard to replace CCriticalSection
with CNamedCriticalSection
and CSingleLock
with CSpinLocK
. Well, it is not hard, it's quite simple actually. Just remember that CNamedCriticalSection
and CSpinLock
constructors need a name string.
Points of Interest
It's interesting:). Seriously, you will need this while coding large applications with a lot of threads.
History
- Version 1.0 - 23rd- February-2005 - As promised in the CDebugTrace article, I have posted this one, too.