Open In App

Lock Variable Synchronization Mechanism

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Prerequisites – Process Synchronization
A lock variable provides the simplest synchronization mechanism for processes. Some noteworthy points regarding Lock Variables are- 

  1. Its a software mechanism implemented in user mode, i.e. no support required from the Operating System.
  2. Its a busy waiting solution (keeps the CPU busy even when its technically waiting).
  3. It can be used for more than two processes.

When Lock = 0 implies critical section is vacant (initial value ) and Lock = 1 implies critical section occupied.
The pseudocode looks something like this – 

Entry section - while(lock != 0);
                Lock = 1;
//critical section
Exit section - Lock = 0;

A more formal approach to the Lock Variable method for process synchronization can be seen in the following code snippet :

C




<div id="highlighter_905493" class="syntaxhighlighter nogutter  "><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="color1 bold">char</code> <code class="plain">buffer[SIZE];</code></div><div class="line number2 index1 alt1"><code class="color1 bold">int</code> <code class="plain">count = 0,</code></div><div class="line number3 index2 alt2"><code class="undefined spaces">    </code><code class="plain">start = 0,</code></div><div class="line number4 index3 alt1"><code class="undefined spaces">    </code><code class="plain">end = 0;</code></div><div class="line number5 index4 alt2"><code class="keyword bold">struct</code> <code class="plain">lock l;</code></div><div class="line number6 index5 alt1"> </div><div class="line number7 index6 alt2"><code class="comments">// initialize lock variable</code></div><div class="line number8 index7 alt1"><code class="plain">lock_init(&l);</code></div><div class="line number9 index8 alt2"> </div><div class="line number10 index9 alt1"><code class="keyword bold">void</code> <code class="plain">put(</code><code class="color1 bold">char</code> <code class="plain">c)</code></div><div class="line number11 index10 alt2"><code class="plain">{</code></div><div class="line number12 index11 alt1"> </div><div class="line number13 index12 alt2"><code class="undefined spaces">    </code><code class="comments">// entry section</code></div><div class="line number14 index13 alt1"><code class="undefined spaces">    </code><code class="plain">lock_acquire(&l);</code></div><div class="line number15 index14 alt2"> </div><div class="line number16 index15 alt1"><code class="undefined spaces">    </code><code class="comments">// critical section begins</code></div><div class="line number17 index16 alt2"><code class="undefined spaces">    </code><code class="keyword bold">while</code> <code class="plain">(count == SIZE) {</code></div><div class="line number18 index17 alt1"> </div><div class="line number19 index18 alt2"><code class="undefined spaces">        </code><code class="plain">lock_release(&l);</code></div><div class="line number20 index19 alt1"><code class="undefined spaces">        </code><code class="plain">lock_acquire(&l);</code></div><div class="line number21 index20 alt2"><code class="undefined spaces">    </code><code class="plain">}</code></div><div class="line number22 index21 alt1"> </div><div class="line number23 index22 alt2"><code class="undefined spaces">    </code><code class="plain">count++;</code></div><div class="line number24 index23 alt1"><code class="undefined spaces">    </code><code class="plain">buffer[start] = c;</code></div><div class="line number25 index24 alt2"><code class="undefined spaces">    </code><code class="plain">start++;</code></div><div class="line number26 index25 alt1"> </div><div class="line number27 index26 alt2"><code class="undefined spaces">    </code><code class="keyword bold">if</code> <code class="plain">(start == SIZE) {</code></div><div class="line number28 index27 alt1"> </div><div class="line number29 index28 alt2"><code class="undefined spaces">        </code><code class="plain">start = 0;</code></div><div class="line number30 index29 alt1"><code class="undefined spaces">    </code><code class="plain">}</code></div><div class="line number31 index30 alt2"> </div><div class="line number32 index31 alt1"><code class="undefined spaces">    </code><code class="comments">// critical section ends</code></div><div class="line number33 index32 alt2"><code class="undefined spaces">    </code><code class="comments">// exit section</code></div><div class="line number34 index33 alt1"><code class="undefined spaces">    </code><code class="plain">lock_release(&l);</code></div><div class="line number35 index34 alt2"><code class="plain">}</code></div><div class="line number36 index35 alt1"> </div><div class="line number37 index36 alt2"><code class="color1 bold">char</code> <code class="plain">get()</code></div><div class="line number38 index37 alt1"><code class="plain">{</code></div><div class="line number39 index38 alt2"> </div><div class="line number40 index39 alt1"><code class="undefined spaces">    </code><code class="color1 bold">char</code> <code class="plain">c;</code></div><div class="line number41 index40 alt2"> </div><div class="line number42 index41 alt1"><code class="undefined spaces">    </code><code class="comments">// entry section</code></div><div class="line number43 index42 alt2"><code class="undefined spaces">    </code><code class="plain">lock_acquire(&l);</code></div><div class="line number44 index43 alt1"> </div><div class="line number45 index44 alt2"><code class="undefined spaces">    </code><code class="comments">// critical section begins</code></div><div class="line number46 index45 alt1"><code class="undefined spaces">    </code><code class="keyword bold">while</code> <code class="plain">(count == 0) {</code></div><div class="line number47 index46 alt2"> </div><div class="line number48 index47 alt1"><code class="undefined spaces">        </code><code class="plain">lock_release(&l);</code></div><div class="line number49 index48 alt2"><code class="undefined spaces">        </code><code class="plain">lock_acquire(&l);</code></div><div class="line number50 index49 alt1"><code class="undefined spaces">    </code><code class="plain">}</code></div><div class="line number51 index50 alt2"> </div><div class="line number52 index51 alt1"><code class="undefined spaces">    </code><code class="plain">count--;</code></div><div class="line number53 index52 alt2"><code class="undefined spaces">    </code><code class="plain">c = buffer[end];</code></div><div class="line number54 index53 alt1"><code class="undefined spaces">    </code><code class="plain">end++;</code></div><div class="line number55 index54 alt2"> </div><div class="line number56 index55 alt1"><code class="undefined spaces">    </code><code class="keyword bold">if</code> <code class="plain">(end == SIZE) {</code></div><div class="line number57 index56 alt2"> </div><div class="line number58 index57 alt1"><code class="undefined spaces">        </code><code class="plain">end = 0;</code></div><div class="line number59 index58 alt2"><code class="undefined spaces">    </code><code class="plain">}</code></div><div class="line number60 index59 alt1"> </div><div class="line number61 index60 alt2"><code class="undefined spaces">    </code><code class="comments">// critical section ends</code></div><div class="line number62 index61 alt1"><code class="undefined spaces">    </code><code class="comments">// exit section</code></div><div class="line number63 index62 alt2"><code class="undefined spaces">    </code><code class="plain">lock_release(&l);</code></div><div class="line number64 index63 alt1"> </div><div class="line number65 index64 alt2"><code class="undefined spaces">    </code><code class="keyword bold">return</code> <code class="plain">c;</code></div><div class="line number66 index65 alt1"><code class="plain">}</code></div></div></td></tr></tbody></table></div>


C++





Here we can see a classic implementation of the reader-writer’s problem. The buffer here is the shared memory and many processes are either trying to read or write a character to it. To prevent any ambiguity of data we restrict concurrent access by using a lock variable. We have also applied a constraint on the number of readers/writers that can have access.
Now every Synchronization mechanism is judged on the basis of three primary parameters : 

  1. Mutual Exclusion.
  2. Progress.
  3. Bounded Waiting.

Of which mutual exclusion is the most important of all parameters. The Lock Variable doesn’t provide mutual exclusion in some cases. This fact can be best verified by writing its pseudo-code in the form of an assembly language code as given below.

1. Load Lock, R0 ; (Store the value of Lock in Register R0.)
2. CMP R0, #0 ; (Compare the value of register R0 with 0.)
3. JNZ Step 1 ; (Jump to step 1 if value of R0 is not 0.)
4. Store #1, Lock ; (Set new value of Lock as 1.)
Enter critical section
5. Store #0, Lock ; (Set the value of lock as 0 again.)

Now let’s suppose that processes P1 and P2 are competing for Critical Section and their sequence of execution be as follows (initial value of Lock = 0) –

  1. P1 executes statement 1 and gets pre-empted.
  2. P2 executes statement 1, 2, 3, 4 and enters Critical Section and gets pre-empted.
  3. P1 executes statement 2, 3, 4 and also enters Critical Section.

Here initially the R0 of process P1 stores lock value as 0 but fails to update the lock value as 1. So when P2 executes it also finds the LOCK value as 0 and enters Critical Section by setting LOCK value as 1. But the real problem arises when P1 executes again it doesn’t check the updated value of Lock. It only checks the previous value stored in R0 which was 0 and it enters critical section.
This is only one possible sequence of execution among many others. Some may even provide mutual exclusion but we cannot dwell on that. According to murphy’s law “Anything that can go wrong will go wrong“. So like all easy things the Lock Variable Synchronization method comes with its fair share of Demerits but its a good starting point for us to develop better Synchronization Algorithms to take care of the problems that we face here. 

FAQ

Q: Are lock variables the best synchronization mechanism in all scenarios?
A: No, while lock variables are a simple mechanism for synchronization, they may not be efficient in scenarios where processes are frequently contending for access to a critical section. In such cases, other synchronization mechanisms like semaphores, monitors, or message passing may be more appropriate.

Q: Can lock variables cause starvation?
A: Yes, lock variables can cause starvation if a process is blocked indefinitely while waiting for access to the critical section. To prevent starvation, techniques like aging or priority inversion can be employed.

Q: Can lock variables be used in conjunction with other synchronization mechanisms?
A: Yes, lock variables can be used in conjunction with other synchronization mechanisms to provide more robust synchronization solutions. For example, a lock variable can be used to implement mutual exclusion while a semaphore can be used to implement a bounded buffer.



Last Updated : 22 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads