Sign In | Register Now About Bytes | Help | Site Map
Connecting Tech Pros Worldwide

Making a class threadsafe / Locking a const accessor

Question posted by: Sirmont (Newbie) on July 8th, 2008 08:35 PM
Good day all,

Is there a logical way to lock data in an accessor?

Because accessors are generally declared as const methods and a lock() operation is not, how can you lock the class internally when the accessor is called?

For example:
Expand|Select|Wrap|Line Numbers
  1. class Class
  2. {
  3. public:
  4.   int GetValue() const;
  5.  
  6. protected:
  7.   void Lock();
  8.   void Unlock();
  9.  
  10. private:
  11.   int m_Value;
  12. }

When I implement GetValue(), i'd like to do:
Expand|Select|Wrap|Line Numbers
  1. int Class::GetValue()
  2. {
  3.   Lock();
  4.   int TmpValue = m_Value;
  5.   Unlock();
  6.   return(TmpValue);
  7. }

But obviously this isn't good, since Lock/Unlock aren't const (and can't be).

I am sure I am not the first to try to make a class thread safe so I guess I'm just missing something...

Thanks!


EDIT: Strangely, I knew of a possible solution and yet it just disappeared from my head: using const_cast on the instance of the class (or lock) would be a valid solution. But would it be the best? What do you think?
Banfa's Avatar
Banfa
AdministratorVoR
5,039 Posts
July 9th, 2008
09:54 PM
#2

Re: Making a class threadsafe / Locking a const accessor
OK this is a guess but you could try declaring lock and unlock mutable (this is a C++ keyword). I believe that would make them modifiable even in a situation that normally requires constness, such as an accessor.

Reply
Sirmont's Avatar
Sirmont
Newbie
12 Posts
July 10th, 2008
02:36 PM
#3

Re: Making a class threadsafe / Locking a const accessor
This is just absolutely perfect! Exactly what I need! Thanks!

Reply
hdanw's Avatar
hdanw
Member
60 Posts
July 11th, 2008
06:49 AM
#4

Re: Making a class threadsafe / Locking a const accessor
May not be what you want.

Can you Identify what the scope is on this Lock() call?

Essentially a mutex m, is either locked, or unlocked.

The OS core, is not selective about who acquires the mutex, when.

So lets say that you are in a multi threaded environment, as is the case when synchronization is required, and you have a mutex, which is inherently associated with the object / instance.

So when you call Lock(), you are in essence calling ParentClass.Lock().

Which means that accessors for other data elements are waiting for exclusive access to that object instance before they can write.

If mutlple calls come in for seperate data members it wont matter. And since the OS is not selective, one accessor can be held indefinately while other accessors do there jobs. Potentially dogging your system. And takeing away any advantage you hoped to gain by being multi-Threaded.

A better way is to create a Critical Section for each Specific Data Item or member. So that calls to that accessor is only blocking other calls to that same accessor. and the Other Accessors can freely access their data simultaneously.

So, to speed up your application serialize the accessors for each data member, instead of serializing access to the intire object instance.


Expand|Select|Wrap|Line Numbers
  1. The steps are easy ...
  2.  
  3. 1. at instantiation call InitializeCriticalSection() for each data member.
  4. 2. in the accessors call EnterCriticalSection() emmediatley prior to the access, 
  5. 3, call LeaveCriticalSection() immediately following access, and finally
  6. 4. DeleteCriticalSection in class Destructor.
  7.  
  8. 1: http://msdn.microsoft.com/en-us/library/ms683472(VS.85).aspx
  9. 2: http://msdn.microsoft.com/en-us/library/ms682608.aspx
  10. 3: http://msdn.microsoft.com/en-us/library/ms684169(VS.85).aspx
  11. 4: http://msdn.microsoft.com/en-us/library/ms682552(VS.85).aspx


Which is much faster than the equivalent mutex operation.

BTW the Lock keyword is a C# thing, that was extended by the CLR.
Without the CLR your application may have issues.

Happy Coding!

Reply
Sirmont's Avatar
Sirmont
Newbie
12 Posts
July 16th, 2008
10:02 PM
#5

Re: Making a class threadsafe / Locking a const accessor
Very relevant comment. I understand why it would be more efficient to have one mutex/critical section per member. In fact I am very couscious of this, but the class I am making thread-safe is basically making operations on a map, so there's pretty much no gain to be made there.

What I don't understand is why should I use a critical section instead of a mutex and how it is different?

Thanks for your input!
J-O

P.-S. My Lock()/Unlock() methods were just examples. In fact I use wxWidgets, so I use wxLock/wxUnlock and wxCriticalSection.

Reply
Banfa's Avatar
Banfa
AdministratorVoR
5,039 Posts
July 17th, 2008
01:39 AM
#6

Re: Making a class threadsafe / Locking a const accessor
A Critical Section is a more limited but lighter version of a mutex.

That is a Critical Section provides less functionality, it in only works inter-thread with-in a single process where as a mutex works inter-process and a critical section is not a OS object so you can't use the Wait... functions to wait on it which you can with a mutex.

However the loss of functionality results in a performance gain, it is quicker to lock/unlock a critical section compared to a mutex.

Reply
Sirmont's Avatar
Sirmont
Newbie
12 Posts
July 24th, 2008
05:44 PM
#7

Re: Making a class threadsafe / Locking a const accessor
Great! Thanks guys! This answers it all...

Reply
Reply
Not the answer you were looking for? Post your question . . .
189,758 Experts ready to help you find a solution.
Sign up for a free account, or Login (if you're already a member).

Latest Articles: Read & Comment
Top C / C++ Forum Contributors