gap between an unlock and a lock..

This is a discussion on gap between an unlock and a lock.. within the C++ Programming forums, part of the General Programming Boards category; Hi, I've got a small question: Code: Telepathic::Message TelepatiaChannel::getMessage(){ hasIncoming.waitUntilTrue(); // point 1 incoming_lock.Lock(); // point 2 assert(incoming.size() > 0); ...

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    108

    gap between an unlock and a lock..

    Hi, I've got a small question:

    Code:
    Telepathic::Message TelepatiaChannel::getMessage(){
       hasIncoming.waitUntilTrue(); // point 1
       incoming_lock.Lock(); // point 2
       assert(incoming.size() > 0); // point 3
       Telepathic::Message msg = incoming.front();
       incoming.pop_front();
       incoming_lock.Unlock();
    
       return msg;
    
    }
    What the code does is pretty simple, it waits for the WaitableBool "hasIncoming" to be true, then it locks incoming_lock..

    The WaitableBool class is from another thread I started months ago : waitable boolean class (concurrency)

    Now the question is, suppose I have two or more threads calling this function, all waiting at point 1. As soon as hasIncoming switches to true, one of the threads will move to point two. Is there a chance that, a thread (say, thread A) will take control inside point 1, and then lose control before it reaches point 2?

    Because this could cause a situation where a thread thinks that there's available data, and comes and finds that there's no data, therefore triggering point 3..

    I'm thinking that I have to actually change the code above, to make the thread wait again if it finds that there's no data.

    So yeah, anybody know if my suspicion is right?

    Thanks in advance

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    108
    This is what I changed it to.. am I overkilling it?

    Code:
       while(true){
          hasIncoming.waitUntilTrue();
          incoming_lock.Lock();
          if(incoming.size() > 0){
             Telepathic::Message msg = incoming.front();
             incoming.pop_front();
             incoming_lock.Unlock();
             return msg;
          } else {
             incoming_lock.Unlock();
          }
          
       }

  3. #3
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,590
    I'm not sure what OS you are using but Windows has solved this problem via critical sections. If two threads enter at the same time one is allowed to 'win' and the other then holds at an implicit WaitForSingleObject. When the thread that 'won' leaves the critical section, the thread that is waiting then proceeds into the critical section and takes ownership of it.

    There is more information on MSDN about critical sections.

  4. #4
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,457
    In general, yes it possible that a thread may gain control at point 1 but lose it just prior to point 2 or somewhere iniside point 2 and another thread would take control at point 2 and lock.
    Until you lock via a mutex or use a critical section, it's a race.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    108
    Cool, understood, thanks!

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    What you need is a condition variable. That's basically your waitable bool, but it atomically locks a mutex before waking the thread, and if the mutex cannot be locked, it keeps waiting.

    POSIX threads natively has condition variables. Windows Vista also offers them. Under XP, you have to emulate them. Boost.Threads offers a condition variable that works cross-platform.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,590
    POSIX threads natively has condition variables. Windows Vista also offers them. Under XP, you have to emulate them. Boost.Threads offers a condition variable that works cross-platform.
    I've tried using condition variables inside of XP with little success. It has been my experience that unless a kernel level object is used it won't work. How would you go about creating a condition variable in a Win32 program? I've tried using bools to 'gate' thread entries to functions and blocks of code with absolutely no success.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    I wouldn't. I'd just use Boost's condition variable.

    The implementation of that is here:
    http://svn.boost.org/trac/boost/brow...n_variable.hpp
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21