CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Installing SQL Server 2008
  • Writing UDFs for Firebird Embedded SQL Server
  • [Updated] Shutdown Manager
  • Building Windows Azure Cloud Service Applications with Azure Storage and the Azure SDK

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > Multithreading
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    Multithreading Discuss multithreading issues and related topics.

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old November 4th, 2009, 02:04 PM
    SquishyOleo SquishyOleo is offline
    Junior Member
     
    Join Date: Jul 2008
    Posts: 8
    SquishyOleo is an unknown quantity at this point (<10)
    Locking An Entire Class

    Hi All,

    I'm having a lot of trouble finding an answer to this - hopefully you can provide some guidance.

    I'm currently in the design phase of a project which is multi-threaded and it maintains an array of connected client objects (CClient). Each CClient object is specific to it's related connection storing information such as statistics, positioning, connection details, etc, etc. This list can be accessed by multiple threads at different times (for reading/writing) and I'm trying to come up with a good way to lock the list during thread accesses. At this point in time I've decided that a per-client lock system would be the best way to go.

    Now for implementation. There are two ways I see this being done but cannot seem to get either to work. The first would be to implement a "gateway" type of function where all calls to a CClient instance would be made through a single function:

    Code:
        getClient().connection.setAddress(".....");
    This "getClient()" function would lock and then unlock the CClient object once "setAddress()" had completed its tasks.

    The second way would be to have specific Lock() and Unlock() member functions of each CClient instance. Then when a thread wants to manipulate the CClient it calls "client.Lock()", does what it needs to, then calls "client.Unlock()". The problem with this method is that I can make CMutex a member variable of the CClient class but can't get CSingleLock set up as a member variable since it needs a pointer to the CMutex object when it's constructed.

    I think I'd prefer using the first method as it internalizes the locking mechanism to the CClient object itself - I'm just not sure how to implement it. Can anyone point me in the proper direction? Or maybe someone has a better idea on how to handle this?

    Thanks!
    Reply With Quote
      #2    
    Old November 4th, 2009, 02:44 PM
    Arjay's Avatar
    Arjay Arjay is offline
    Moderator / MS MVP
    Power Poster
     
    Join Date: Aug 2004
    Posts: 6,302
    Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)
    Re: Locking An Entire Class

    Here's what I would do:

    1) You'll need to lock access to the list that tracks the clients.
    2) Lock each client methods. Put a critical section object in each client and wrap the client operations with Getters/Setters. Inside the getters/setters lock and unlock the cs.

    See my signature line for more multi-threading articles and posts.
    Reply With Quote
      #3    
    Old November 5th, 2009, 10:22 AM
    SquishyOleo SquishyOleo is offline
    Junior Member
     
    Join Date: Jul 2008
    Posts: 8
    SquishyOleo is an unknown quantity at this point (<10)
    Re: Locking An Entire Class

    Thanks for the suggestion Arjay. It looks as if that's the way I'm going to have to go. The only problem I see is that I need to check the status of the CClient object to determine if it is locked or not. CCriticalSection doesn't provide any provision to do that. The MSDN shows that CCriticalSection::Lock() can take a timeout as a parameter but then further down states that "Lock ignores this parameter value". I could use a boolean flag for the locking state status but why use an extra variable if I don't have to - one less thing to have to worry about. C[Single][Multi]Lock at least provide an IsLocked() method. Actually come to think of it now I could just derive a new class from CCriticalSection, encapsulate that boolean state flag in it and give it an IsLocked() method. That'll work.

    Last edited by SquishyOleo; November 5th, 2009 at 10:36 AM.
    Reply With Quote
      #4    
    Old November 5th, 2009, 02:20 PM
    Arjay's Avatar
    Arjay Arjay is offline
    Moderator / MS MVP
    Power Poster
     
    Join Date: Aug 2004
    Posts: 6,302
    Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)Arjay has a reputation beyond repute (3000+)
    Re: Locking An Entire Class

    Why do you need to check the state? Just attempt to get a lock and if you can't get a lock, you'll know another thread has a lock and will release it soon.

    I've written some synch classes that are lightweight wrappers around the critical section, mutex, and a readerwriter lock object. I also have an CAutoLock class that provides the RAII form of locking (which automatically unlocks the synch object as it goes out of scope).

    The following is an example of pushing an item onto a queue

    Code:
    HRESULT PushItem( CItem* pItem )
    {
      HRESULT hr = S_OK;
      
      CAutoLockT< CItemQueue > lock( &m_ItemQueue );
     
      try
      {
        m_ItemQueue.push( pItem );
      }
      catch( std::bad_alloc )
      {
        hr = E_OUTOFMEMORY;
      } 
      return hr;
    }


    The CAutoLockT line locks the CItemQueue lock object. You'll notice that I don't check to find out if the queue is locked before I attempt to lock it, because I don't care if it's locked. If it's already locked by another thread, my thread will block for a very short time. When the other thread has finished, my thread will obtain the lock. Because I'm using the RAII approach, I'm guaranteed that the lock will always get released even if the push operation throws some unexpected exception. With RAII, I don't have to ever worry about unlocking the object which makes my code cleaner.

    I'm posting the CAutoLockT snippet above, just to illustrate that you don't need to check if an object is locked first. I code all my threading with the same pattern and have yet to run into trouble.
    Reply With Quote
      #5    
    Old November 6th, 2009, 03:29 PM
    SquishyOleo SquishyOleo is offline
    Junior Member
     
    Join Date: Jul 2008
    Posts: 8
    SquishyOleo is an unknown quantity at this point (<10)
    Re: Locking An Entire Class

    The original purpose of being able to check for whether or not a CClient is locked was to allow for a separate thread to be able to check to see if, for instance, a client was ready to be shut down or not without stopping it's own execution. But now that you mention the method of just trying to get the lock and waiting for "your turn" does make more sense. If I want to shut the thread down, I'm going to want to make sure I, and nobody else, has the client. Thanks for the suggestion.
    Reply With Quote
      #6    
    Old November 16th, 2009, 04:48 AM
    code_carnage code_carnage is offline
    Member
     
    Join Date: May 2007
    Location: Mumbai India
    Posts: 245
    code_carnage will become famous soon enough (80+)
    Re: Locking An Entire Class

    See...Your threads must be running on some condition...

    something like this..
    Code:
    void svc()
    {
       while(isRunning)
       {
          //do something.
       }
    
    }
    Now from main thread/Parent thread. You will set isRunning as false..and you will wait/join on thread handle object..

    Ooops...!! volatile, instead of transient..
    Dont forget to declare isRunning a transient..
    __________________
    Dont forget to rate my post if you find it useful.

    Last edited by code_carnage; November 16th, 2009 at 06:01 AM.
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > Multithreading


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 01:00 AM.



    Acceptable Use Policy

    internet.comMediabistrojusttechjobs.comGraphics.com

    WebMediaBrands Corporate Info


    Advertise | Newsletters | Feedback | Submit News

    Legal Notices | Licensing | Permissions | Privacy Policy


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
    Copyright WebMediaBrands Inc. 2002-2009