Solved

URGENT: CSingleLock, CMultiLock, and CCriticalSection

Posted on 2003-10-21
13
1,260 Views
Last Modified: 2013-11-20
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
Comment
Question by:2b_or_not_2bxx
  • 2
  • 2
  • 2
  • +3
13 Comments
 
LVL 3

Accepted Solution

by:
Catalepsy earned 168 total points
ID: 9594705
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
 
LVL 3

Expert Comment

by:Catalepsy
ID: 9594825
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
 
LVL 4

Assisted Solution

by:inox
inox earned 166 total points
ID: 9595232
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:2b_or_not_2bxx
ID: 9595818
I'm sorry, but I'm still not getting.

Can you provide an example?
0
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 166 total points
ID: 9596604
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9596617
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
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 9596691
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
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 9596765
I didn't see ur last post :o(
Rosh
0
 
LVL 4

Expert Comment

by:inox
ID: 9597826
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 9609358
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

685 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question