Seriliazing threads

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • manjuks
    New Member
    • Dec 2007
    • 72

    Seriliazing threads

    Hi All,

    I need some clarification on on mutex.

    Is it possible to use an normal locking (As shown in below code) to serialize access to critical section in threads.

    Code:
    int lock;
    if(lock!= 1){
       lock++;
       //do something here
       lock--;
    }
    if we cant use this to serialize threads, Can you please explain me or give me a pointer where i can read on this.

    Thanks in adavance

    Reagards,
    Manjunath
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Nope, this won't work.

    That's because lock++ and lock-- are a series of machine instructions. In a multithreaded program, you can be interrupted at any machine instruction. Therefore, one thread could get the lock value and get interupted before the ++ was applied and the value returned to the variable. That makes another thread able to get the sam lock value. That's your race condition.

    What you need is a function that cannot be interupted. These functions are provided by the operating system that you are using. What they do is stop the entire operating system except for one thread. Then that thread that do lock++. After that the operating system must be re-enabled to run many threads.

    This is called a critical section.

    For Windows it looks like:

    Code:
    CRITICAL_SECTION  var;
    
    InitializeCriticalSectio(&var);  //initialize var
    
    EnterCriticalSection(&var);
    //All other threads are blocked
    
    ++lock;  //set your lock value
    
    LeaveCriticalSection(&var);
    
    //the lock value is guaranteed unique
    When you are done with var you will need delete the critical section.

    This is all covered in Windows via C/C++ by Jeffrey Richter.

    If you are not using Windows, then I can't help you but I do know the principle of creating, entering and leaving critical sections still applies.

    Lastly, a critical section only applies to a single process. If you need to syunchronize multiple processes, then you need to research using a mutex.

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      You cannot reliably serialize threads through C instructions alone -- you need library functions that make use of local processor or operating system features.

      For example, suppose lock is initially 0. One thread reaches line 2 and determines that execution should flow to line 3. However, at this point another thread takes over. This new thread also finds lock to be 0 and proceeds through line 3 to line 4. Suppose the first thread then wakes up, proceeds through line 3 to line 4. We now have two threads executing the protected code at line 4. Woe is us.

      A reliable locking mechanism requires atomic test-and-set, fetch-and-add, compare-and-swap, or similar operation. Many processors provide these features, but there is no portable way to invoke them from C source code.

      Comment

      • manjuks
        New Member
        • Dec 2007
        • 72

        #4
        Hi thanks weaknessforcats and donbock.
        I understood that the above code will not work, I just want to know weather mutex and semaphores are non preemptive?
        Wont it these get interrupted in between?

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Using a mutex or semaphore is non-preemptive provided you use the OS suppplied functions for working with these objects. That is, a preemptive mutex or semaphore is useless. Indedd, it is the non-preemptive quality that prpvides their value.

          If you write your own mutex or semaphore code then all bets are off. The OS supplied functions have Ring 0 authority which you do not and are therefore not interruptible.

          Note that using a crtical section where you call EnterCriticalSe ction blocks every other thread in your process forever until you call LeaveCritcalSec tion. If tou never make that leave call you process is doomed to the current thread forever.

          Ideally, you enter the critical section, set your lock value and leave the critical section. From then on you just test the lock value on the various threads. Sice the test is a rewad-only you do not enter a critical section to do the test.

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #6
            Preemption within a critical region is possible; in fact that's what makes it so hard to write reliable locking code in C. Locking a critical region in one thread does not prevent the other threads from running -- it only prevents them from entering the locked critical region. The locked-out threads do not need to block on the lock if they can find something useful to do in the meantime.

            Comment

            Working...