Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1356
  • Last Modified:

URGENT: CSingleLock, CMultiLock, and CCriticalSection

I'm having a hard time understanding the difference between CSingleLock, CMultiLock, and CCriticalSection.

In reading the MSDN database, the descriptions seem to be nearly the same.

Can some one please explain the diferences in plain english.
0
2b_or_not_2bxx
Asked:
2b_or_not_2bxx
  • 2
  • 2
  • 2
  • +3
3 Solutions
 
CatalepsyCommented:
Basically, the difference is for CSingleLock you would use this in a case where there is only one resource you would be waiting on at a given time.  CMultiLock should be used when you would wait on multiple resources at a given time.  A critical section means once you reach a certain point in your code you want to ensure only one thread is accessing it at a time.

0
 
CatalepsyCommented:
For instance,

   Suppose you have a member variable called counter.  You might want to ensure only one thread is reading/writing the counter at a given time.  This would be a good case for CSingleLock.  Wait for the counter resource (lock), when acquired, read the counter or modify the counter then release the counter resource (lock).

   Suppose you have a situation where you need one or more things to occur before you perform some work.  For example, say you have a reader thread that reads a socket.  Now, let us say an error occurred and you need to reconnect.  In this case, you might wait on an event (saying an error occurred) or you might wait for the reader thread to die.  In this case, you might wait on the two objects when one or more events occur (mutexes are released, threads die, events are triggered) you create a new reader thread and reconnect the socket.  This may seem kind of like poor example, but the idea is, you will be waiting on one or more events to occur (you specify).  With WaitForMultipleObject(...) you can also specify to wait when all objects are ready or just one.  In the previous example, you could wait for either an error, or the thread died or wait for an error and the thread to die.

   The way I see it, a critical section and a single lock could be used to solve the same type of problem.  A critical section should only allow one thread to run in a section of code at one point in time.  I believe in this case, the thread should be able to run uninterrupted (might be OS dependent) until it has reached the end.  All other threads will be prevented from running if they need in the critical section if another thread is running inside.
0
 
inoxCommented:
CSingleLock or CMultiLock are 'extensions' of a CriticalSection.
you can only call CriticalSection.lock to enter a Critical section any you 'hang' if already locked until released (if called from differnt threads of course)
with a CSingleLock you can Check and enter the according Criticalsection, so you have a backdoor to bypass if locked.
CMultiLock is the same for multiple sections.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
2b_or_not_2bxxAuthor Commented:
I'm sorry, but I'm still not getting.

Can you provide an example?
0
 
AlexFMCommented:
Suppose you have some cthread-safe class which has member:

CCriticalSection m_section;

Every function of this class is protected by this member using the following way:

void SMyClass::SomeOperation()
{
    m_section.Lock();

    // make operation

    m_section.Unlock();
}

Operations betweel Lock and Unlock may be thinked as atomic, this function may be called from different threads:

thread 1:  pClass->SomeOperation();    // 1
thread 2:  pClass->SomeOperation();    // 2
thread 3:  pClass->SomeOperation();    // 3

2 starts only when 1 finished. 3 starts only when 2 finished. Code between Lock and Unlock is thread-safe and cannot be intercepted from another threrad.

Suppose your function has some complicated structure:

void SMyClass::SomeOperation()
{
    m_section.Lock();

    if (  ... )
    {
        m_section.Unlock();
        return;
    }

    if (  ... )
    {
        m_section.Unlock();
        return;
    }

    ...

    m_section.Unlock();
}

You need to unlock critical section before every return line. If you forger to do this, critical section remains locked and you have a deadlock. Here CSingleLock can help:


void SMyClass::SomeOperation()
{
    CSingleLock lock(&m_section, TRUE);

    m_section.Lock();

    if (  ... )
    {
        return;
    }

    if (  ... )
    {
        return;
    }

    ...
}

All you need is to add the line
CSingleLock lock(&m_section, TRUE);
to the start of the function. It locks critical section. When function finished, lock object is destroyed and unlocks critical section in it's destructor.

0
 
AlexFMCommented:
CMultiLock works like CSingleLock, but allows to work with number of synchronization objects. It is initialized with array to number of objects, and unlocks all of them in it's destructor. In most of cases, writing safe-thread class we need CSingleLOck.
0
 
Roshan DavisCommented:
adding some more Alex's comment

CMultiLock

This class allows you to block, or wait, on up to 64 synchornization objects at once. You create an array of references to the objects, and pass this to the constructor. In addition, you can specify whether you want it to unblock when one object unlocks, or when all of them do.


//let's pretend these are all global objects, or defined other than in the local function
CCriticalSection cs;
CMutex mu;
CEvent ev;
CSemaphore sem[3];

.
.
.
CSynObject* objects[6]={&cs,&mu,&ev,&sem[0],&sem[1],&sem[2]};

CMultiLock mlock(objects,6);
int result=mlock.Lock(INFINITE,FALSE);
.
.
.
 



Notice you can mix synchronization object types. The two parameters I specified (both optional) specify the time-out period and whether to wait for all the objects to unlock before continuing. I saved the return value of Lock() because that is the index into the array of objects of the one that unblocked, in case I want to do special processing.
0
 
Roshan DavisCommented:
I didn't see ur last post :o(
Rosh
0
 
inoxCommented:
Hi 2b_or_not_2bxx,
imagin you have a string and two threads, one thread modifies the string and the other thread reads the string. Now happens the threadswitch but the first thread finished the stringmodification only half -> the 2. thread reads wrong! So the string access can be protected by a critical section (cs) to avoid that, so both threads call cs.Lock() before accessing the thread and cs.Unlock() after.
BUT:
when a thread calls cs.Lock() this thread will be suspended (hangs in that function) until the cs is unlocked by the caller. You never know how long this can take, so there may be situations where this is unacceptable, because the thread should continue (for other things) so this thread uses a CSingeLock (sl) (assigned to that cs), which is more flexible because you can call IsLocked() wich enters the section if not locked, but return if  it is, so you can continue doing other things.
CMultilock (ml) is the same for multiple cs.
cs is just and example for sl and ml to operate with, there are others as you know from msdn.
0
 
DanRollinsCommented:
sorry, I still don't get it.  All of these letters and numbers are just confusing me.  Could someone please beam the information directly into my head?  Thanks!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 2
  • 2
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now