Concurrency mutual exclusion and synchronization
Download
1 / 33

Concurrency: Mutual Exclusion and Synchronization - PowerPoint PPT Presentation


  • 86 Views
  • Uploaded on

Concurrency: Mutual Exclusion and Synchronization. Chapter 5. Critical Sections & Mutual Exclusion. shared double balance ; Code for p 1 Code for p 2 . . . . . . balance = balance + amount; balance = balance - amount; . . . . . . balance += amount. balance -= amount. Shared.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Concurrency: Mutual Exclusion and Synchronization' - stu


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Concurrency mutual exclusion and synchronization

Concurrency: Mutual Exclusion and Synchronization

Chapter 5


Concurrency mutual exclusion and synchronization

Critical Sections & Mutual Exclusion

shared double balance;

Code for p1Code for p2

. . . . . .

balance = balance + amount; balance = balance - amount;

. . . . . .

balance += amount

balance -= amount

Shared

balance

Assembly code for p1 Assembly code for p2

load R1, balance load R1, balance

load R2, amount load R2, amount

add R1, R2 sub R1, R2

store R1, balance store R1, balance


Critical sections cont
Critical Sections (cont.)

  • Mutual exclusionOnly one process can be in the critical section at a time

    Without mutual exclusion, results of multiple execution are notconsistent

  • There is a race to execute critical sections

  • The sections may be defined by different code in different processes. Therefore, it is not easy for compilers to detect them

    Need an OS mechanism so programmer can resolve races

Some Possible OS Mechanisms

  • Disable interrupts

  • Software solution – locks, semaphores


Disabling interrupts
Disabling Interrupts

shared double balance;

Code for p1Code for p2

disableInterrupts(); disableInterrupts();

balance = balance + amount; balance = balance - amount;

enableInterrupts(); enableInterrupts();

  • Disabling interrupts guarantees mutual exclusion, but …

Disadvantages

  • A user process can easily abuse this privilege and hence should not be available to a user process.

  • Interrupts could be disabled arbitrarily long

  • We only want to prevent p1 and p2 from interfering with one another; this prevents any other process pk to execute

  • In a Multiprocessor system, disabling interrupts in one processor will not disable it in another process and hence mutual exclusion is not guaranteed


Using a lock variable
Using a lock Variable

shared booleanlock = FALSE;

shared double balance;

Code for p1Code for p2

/* Acquire the lock *//* Acquire the lock */

while (lock) /*loop */ ; while (lock) /*loop */ ;

lock = TRUE; lock = TRUE;

/* Execute critical sect *//* Execute critical sect */

balance = balance + amount; balance = balance - amount;

/* Release lock *//* Release lock */

lock = FALSE; lock = FALSE;

  • Access to lock is not atomic, race condition is still there!

  • Is it possible to solve the problem?


New solution
New Solution

shared booleanlock = FALSE;

shared list L;

Code for p1Code for p2

. . . . . .

get(lock);get(lock);

<execute critical section>;<execute critical section>;

release(lock);release(lock);

. . . . . .

However, get(lock) and release(lock) operations must be atomic !


Important considerations for software locks
Important considerations for software locks

  • Mutual exclusion:

    Only one process at a time in the Critical Section (CS)

  • Only the processes competing for a CS must be considered for resolving who enters the CS next.

  • Once a process attempts to enter its CS, it should not be postponed indefinitely  NO STARVATION!

    (After requesting entry, only a bounded number of other processes may enter before the requesting process)

  • No deadlock or starvation should occur

  • A process should not be delayed access to a critical section when there is no other process using it

  • No assumptions should be made about the relative speeds of processes or the number of competing processes


Dijkstra s semaphore
Dijkstra’s Semaphore

  • Invented in the 1960s

  • Conceptual OS mechanism, with no specific implementation defined (could be get()/release())

  • Basis of all contemporary OS synch. mechanisms

  • A semaphore, s, is a nonnegative integer variable that can only be changed or tested by these two atomic (indivisible / uninterruptable) functions:

    P(s) : [ while(s == 0) {wait}; s = s – 1; ]

    V(s) : [ s = s + 1;]


Semaphore solution
Semaphore solution

structsemaphore {

intcount;

queueTypequeue;

}

void get(semaphore s)

disable_interrupts();

{ s.count--;

if (s.count < 0)

{place this process in s.queue;

block this process

}

enable_interrupts();

}

void release(semaphore s)

{disable_interrupts();

s.count++;

if (s.count <= 0)

{ remove a process P from s.queue;

place process P on ready queue;

}

enable_interrupts();

}

get( )  P( )  wait( )

 pthread_mutex_lock()

release( )  V( )  signal( )

 pthread_mutex_unlock()


Shared account problem
Shared Account Problem

  • P0()

  • {

  • . . .

  • /* Enter the CS */

  • P(mutex);

  • balance += amount;

  • V(mutex);

    • . . .

  • }

    • P1()

    • {

    • . . .

    • /* Enter the CS */

    • P(mutex);

    • balance -= amount;

    • V(mutex);

      • . . .

  • }

  • semaphore mutex = 1;

    pthread_create(P0, 0);

    pthread_create(P1, 0);


    Semaphore critical section example
    Semaphore/Critical Section example

    A is done!

    What is going to happen now?


    Processing two critical sections
    Processing Two Critical Sections

    shared lock1 = FALSE;

    shared lock2 = FALSE;

    Code for p1

    . . .

    /* Enter CS-1 */

    get(lock1);

    <critical section 1>;

    release(lock1);

    <other computation>;

    /* Enter CS-2 */

    get(lock2);

    <critical section 2>;

    release(lock2);

    . . .

    shared lock1 = FALSE;

    shared lock2 = FALSE;

    Code for p2

    . . .

    /* Enter CS-2*/

    get(lock2);

    <critical section 2>;

    release(lock2);

    <other computation>;

    /* Enter CS-1 */

    get(lock1);

    <critical section 1>;

    release(lock1);

    . . .


    Deadlock may occur if locks are not used properly
    Deadlockmay occur if locks are not used properly!

    shared boolean lock1 = FALSE;

    shared boolean lock2 = FALSE;

    Code for p1Code for p2

    . . . . . .

    get(lock1); get(lock2);

    <delete element>; <update length>;

    /* Enter CS to update length */ /* Enter CS to add element */

    get(lock2); get(lock1);

    <update length>; <add element>;

    release(lock2); releaselock1);

    release(lock1); release(lock2);

    . . . . . .


    Os concerns related to concurrency
    OS concerns related to concurrency

    • Synchronization (support for mutual exclusion)

    • Deadlock

    • Resouce Allocation / deallocation

      • Processor

      • Memory

      • Files

      • I/O devices

    • Protection of data/resources (access control for sharing)


    Producer consumer problem
    Producer/Consumer Problem

    • One or more producers are generating data and placing these in a buffer

    • A single consumer is taking items out of the buffer one at time

    Producer:

    while (true) {

    /* produce item v */

    b[in] = v;

    in++;

    }

    Consumer:

    while (true) {

    while (in <= out) /* wait */;

    w = b[out];

    out++;

    /* consume item w */

    }

      Infinite Buffer

    Since Buffer b[], “in” and “out” pointers are all shared, these solutions do not work!

    Only one producer or consumer should access the buffer at any one time !


    Producer consumer using a circular buffer
    Producer/Consumer using a Circular Buffer

    Consumer:

    while (true) {

    while (in == out)

    /* do nothing */;

    w = b[out];

    out = (out + 1) % n;

    /* consume item w */

    }

    Producer:

    while (true) {

    /* produce item v */

    while((in + 1)%n == out)

    /* do nothing */;

    b[in] = v;

    in = (in + 1) % n

    }

    Since Buffer b[], “in” and “out” pointers are all shared, these solutions do not work, either!


    A solution to bounded buffer producer consumer problem
    A Solution to Bounded-Buffer Producer/Consumer Problem

    /* lock for Full Pool */

    /* of items in Full Pool */

    Bounded Buffer

    Empty Pool

    Producer

    Consumer

    Producer

    Consumer

    Producer

    Full Pool


    Concurrency mutual exclusion and synchronization

    Readers-Writers Problem

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Reader

    Shared Resource


    Concurrency mutual exclusion and synchronization

    Readers-Writers Problem

    Writer

    Writer

    Writer

    Writer

    Writer

    Writer

    Writer

    Reader

    Reader

    Reader

    Reader

    Reader

    Reader

    Reader

    Reader

    Shared Resource


    Concurrency mutual exclusion and synchronization

    Readers-Writers Problem

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Writer

    Reader

    Reader

    Writer

    Shared Resource


    Concurrency mutual exclusion and synchronization

    First Solution

    reader() {

    while(TRUE) {

    <other computing>;

    P(mutex);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex);

    /* Critical section */

    access(resource);

    P(mutex);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex);

    }

    }

    resourceType *resource;

    intreadCount = 0;

    semaphore mutex = 1;

    semaphore writeBlock = 1;

    writer() {

    while(TRUE) {

    <other computing>;

    P(writeBlock);

    /* Critical section */

    access(resource);

    V(writeBlock);

    }

    }

    • First reader competes with writers

    • Last reader signals writers


    Concurrency mutual exclusion and synchronization

    2

    4

    5

    3

    1

    First Solution

    reader() {

    while(TRUE) {

    <other computing>;

    P(mutex);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex);

    /* Critical section */

    access(resource);

    P(mutex);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex);

    }

    }

    resourceType *resource;

    intreadCount = 0;

    semaphore mutex = 1;

    semaphore writeBlock = 1;

    writer() {

    while(TRUE) {

    <other computing>;

    P(writeBlock);

    /* Critical section */

    access(resource);

    V(writeBlock);

    }

    }

    • First reader competes with writers

    • Last reader signals writers

    • Any writer must wait for all readers

    • Readers can starve writers

    • “Updates” can be delayed forever

      not desirable!


    Concurrency mutual exclusion and synchronization

    4

    5

    3

    2

    1

    Writers Take Precedence

    reader() {

    while(TRUE) {

    <other computing>;

    P(readBlock);

    P(mutex1);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex1);

    V(readBlock);

    access(resource);

    P(mutex1);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex1);

    }

    }

    intreadCount=0, writeCount=0;

    semaphore mutex1=1, mutex2=1;

    Semaphore readBlock=1,writeBlock=1

    writer() {

    while(TRUE) {

    <other computing>;

    P(mutex2);

    writeCount++;

    if(writeCount == 1)

    P(readBlock);

    V(mutex2);

    P(writeBlock);

    access(resource);

    V(writeBlock);

    P(mutex2)

    writeCount--;

    if(writeCount == 0)

    V(readBlock);

    V(mutex2);

    }

    }


    Concurrency mutual exclusion and synchronization

    5

    4

    3

    2

    1

    Writers Take Precedence

    reader() {

    while(TRUE) {

    <other computing>;

    P(readBlock);

    P(mutex1);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex1);

    V(readBlock);

    access(resource);

    P(mutex1);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex1);

    }

    }

    intreadCount=0, writeCount=0;

    semaphore mutex1=1, mutex2=1;

    semaphore readBlock=1,writeBlock=1

    writer() {

    while(TRUE) {

    <other computing>;

    P(mutex2);

    writeCount++;

    if(writeCount == 1)

    P(readBlock);

    V(mutex2);

    P(writeBlock);

    access(resource);

    V(writeBlock);

    P(mutex2)

    writeCount--;

    if(writeCount == 0)

    V(readBlock);

    V(mutex2);

    }

    }


    Concurrency mutual exclusion and synchronization

    6

    7

    5

    4

    3

    Writers Take Precedence

    reader() {

    while(TRUE) {

    <other computing>;

    P(readBlock);

    P(mutex1);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex1);

    V(readBlock);

    access(resource);

    P(mutex1);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex1);

    }

    }

    intreadCount=0, writeCount=0;

    semaphore mutex1=1, mutex2=1;

    semaphore readBlock=1,writeBlock=1

    writer() {

    while(TRUE) {

    <other computing>;

    P(mutex2);

    writeCount++;

    if(writeCount == 1)

    P(readBlock);

    V(mutex2);

    P(writeBlock);

    access(resource);

    V(writeBlock);

    P(mutex2)

    writeCount--;

    if(writeCount == 0)

    V(readBlock);

    V(mutex2);

    }

    }

    • Writers can starve readers

    • “Reads” can be delayed forever

    • Not desirable, either !


    Concurrency mutual exclusion and synchronization

    4

    3

    2

    1

    Fair to Readers and Writers ?

    reader() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(readBlock);

    P(mutex1);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex1);

    V(readBlock);

    V(writePending);

    access(resource);

    P(mutex1);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex1);

    }

    }

    int readCount = 0, writeCount = 0;

    semaphore mutex1 = 1, mutex2 = 1;

    semaphore readBlock = 1, writeBlock = 1, writePending = 1;

    writer() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(mutex2);

    writeCount++;

    if(writeCount == 1)

    P(readBlock);

    V(mutex2);

    P(writeBlock);

    access(resource);

    V(writeBlock);

    V(writePending);

    P(mutex2)

    writeCount--;

    if(writeCount == 0)

    V(readBlock);

    V(mutex2);

    }

    }


    Concurrency mutual exclusion and synchronization

    4

    5

    3

    2

    1

    Fair to Readers and Writers ?

    reader() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(readBlock);

    P(mutex1);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex1);

    V(readBlock);

    V(writePending);

    access(resource);

    P(mutex1);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex1);

    }

    }

    int readCount = 0, writeCount = 0;

    semaphore mutex1 = 1, mutex2 = 1;

    semaphore readBlock = 1, writeBlock = 1, writePending = 1;

    writer() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(mutex2);

    writeCount++;

    if(writeCount == 1)

    P(readBlock);

    V(mutex2);

    P(writeBlock);

    access(resource);

    V(writeBlock);

    V(writePending);

    P(mutex2)

    writeCount--;

    if(writeCount == 0)

    V(readBlock);

    V(mutex2);

    }

    }


    Concurrency mutual exclusion and synchronization

    4

    5

    3

    Fair to Readers and Writers ?

    reader() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(readBlock);

    P(mutex1);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex1);

    V(readBlock);

    V(writePending);

    access(resource);

    P(mutex1);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex1);

    }

    }

    int readCount = 0, writeCount = 0;

    semaphore mutex1 = 1, mutex2 = 1;

    semaphore readBlock = 1, writeBlock = 1, writePending = 1;

    writer() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(mutex2);

    writeCount++;

    if(writeCount == 1)

    P(readBlock);

    V(mutex2);

    P(writeBlock);

    access(resource);

    V(writeBlock);

    V(writePending);

    P(mutex2)

    writeCount--;

    if(writeCount == 0)

    V(readBlock);

    V(mutex2);

    }

    }


    Concurrency mutual exclusion and synchronization

    4

    5

    6

    3

    Fair to Readers and Writers ?

    reader() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(readBlock);

    P(mutex1);

    readCount++;

    if(readCount == 1)

    P(writeBlock);

    V(mutex1);

    V(readBlock);

    V(writePending);

    access(resource);

    P(mutex1);

    readCount--;

    if(readCount == 0)

    V(writeBlock);

    V(mutex1);

    }

    }

    int readCount = 0, writeCount = 0;

    semaphore mutex1 = 1, mutex2 = 1;

    semaphore readBlock = 1, writeBlock = 1, writePending = 1;

    writer() {

    while(TRUE) {

    <other computing>;

    P(writePending);

    P(mutex2);

    writeCount++;

    if(writeCount == 1)

    P(readBlock);

    V(mutex2);

    P(writeBlock);

    access(resource);

    V(writeBlock);

    V(writePending);

    P(mutex2)

    writeCount--;

    if(writeCount == 0)

    V(readBlock);

    V(mutex2);

    }

    }


    Dining philosophers
    Dining Philosophers

    while(TRUE) {

    think();

    get2chopsticks();

    eat();

    }


    Dining philosophers1
    Dining Philosophers

    Anything wrong with this code?

    while(TRUE) {

    think();

    getchopstick-R();

    getchopstick-L();

    eat();

    }


    Here the barbershop problem
    **here The Barbershop Problem

    semaphore max_capacity = 20, sofa = 4, barber_chair = 3, coord = 3;

    semaphorecust_ready = 0, finished = 0, leave_b_chair = 0, payment= 0, receipt = 0;

    void customer ()

    {

    wait(max_capacity);

    enter_shop();

    wait(sofa);

    sit_on_sofa();

    wait(barber_chair);

    get_up_from_sofa();

    signal(sofa);

    sit_in_barber_chair;

    signal(cust_ready);

    wait(finished);

    leave_barber_chair();

    signal(leave_b_chair);

    pay();

    signal(payment);

    wait(receipt);

    exit_shop();

    signal(max_capacity)

    }

    • void barber()

    • {

    • while (true)

    • {

      • wait(cust_ready);

      • wait(coord);

      • cut_hair();

      • signal(coord);

      • signal(finished);

      • wait(leave_b_chair);

      • signal(barber_chair);

    • }

    • }


    Concurrency mutual exclusion and synchronization

    The Barbershop (cont.)

    void cashier()

    {

    while (true)

    {

    wait(payment);

    wait(coord);

    accept_pay();

    signal(coord);

    signal(receipt);

    }

    }

    void main()

    {

    parbegin (customer, . . . 50 times . . . customer,

    barber, barber, barber, cashier);

    }