group19 semaphore

Upload: ksenthil77

Post on 04-Jun-2018

269 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/13/2019 Group19 Semaphore

    1/68

    Site Map0. What Is This Website All About?

    1. Introduction

    1.1 Motivation

    1.2 Everyday Examples

    1.3 Definition

    2. Implementation

    2.1 Implementation of Semaphores

    2.2 Classical Problems

    2.2.1 Sleeping Barber

    2.2.2 Cigarette Smokers

    2.2.3 Unisex Bathroom

    2.3 POSIX Library

    2.3.1 POSIX Mutexes

    2.3.2 POSIX Semaphores

    2.4 Case Study on Prex Semaphore

    3. Advantages and Disadvantages

    4. Alternatives

    5. Conclusion

    Page 1 of 1Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/sitemap.html

  • 8/13/2019 Group19 Semaphore

    2/68

    [ Up: Site Map | Next: 1. Introduction ]

    0. What Is This Website All About?

    Were you thinking the same as well, semaphore = musical instrument?

    WELL WE HOPE NOT!!

    In a sentence, a semaphore, is a tool that has given birth to todays world of

    efficient multitasking, which portrays an illusion of parallelism.

    Multitasking, well, taking the analogy of the MRT in Singapore; for example,

    imagine that there is a bridge (resource) connecting to ends of a railway track,

    and two trains( process) on opposite sides, facing each other, who want to use

    the particular stretch of track to continue on their journey. It is not possible for

    both of the trains to cross at the same time as they would collide. This is where

    a station master (semaphore) comes in, to co-ordinate events (multitask).

    Hence, multitasking is, a state when multiple tasks a.k.a. processes want to use

    a common resource.

    Geek 1 : Huh, s-e-m-a, sema-p-h-o-r-e, semaphore, man this is hard.Whats that all about?Geek 2 : Dunno leh, but using my great powers of intuition, I guess itssome sort of musical instrument, like saxophone, la.Geek 1 : Yeah lor, I guess so. Makes sense. Thanks aa..

    Geek 1 : Oh really? Wah..very nice.Geek 2 : Yeah yeah, I too agree, nice nice.Geek 1 : But I have a question, what is multitasking?Geek 2 : Me too, same question..

    Page 1 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/overview.html

  • 8/13/2019 Group19 Semaphore

    3/68

    Well semaphores have helped resolve some of the problems that operating

    system have suffered from. Examples of such problems are:

    Synchronization

    Race Condition

    Mutual Exclusion

    Starvation

    Deadlock

    Livelock

    Yes we would! With pleasure.

    To get things started, we would guide you from the conception of semaphore in

    1965, by the erratic and undoubtedly one of the greatest geniuses in the field,

    Edsger Dijkstra, to the present day, where certain tweaks have been made.

    So what marked the beginning of all this, it was the era of the swinging

    sixties. To let yourself get enveloped in the fun, exciting and remarkably logical

    world of multiprogramming, please read ahead.

    Hope you have as much fun reading, as we did compiling!

    Have a blast!!

    [ Up: Site Map | Next: 1. Introduction ]

    Geek 1 : Ah I get it.Geek 2 : Me too!Geek 1 : So is that it, just helps trains cross?

    Geek 1 : Wa liao!! Dun understand.Geek 2 : Nehmin, they will explain.

    Page 2 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/overview.html

  • 8/13/2019 Group19 Semaphore

    4/68

    [ Previous: 0. What Is This Website All About? | Up: Site Map | Next: 1.1.

    Motivation ]

    1. IntroductionIn this introduction to semaphore, you will be guided through three different

    aspects to have a rough but good understanding of semaphore. You will see the

    motivation to invent such a technique to solve computing problems, dailyexamples analogical to semaphore and finally the formal definition. Begin your

    journey by clicking on the destinations below.

    1.1 Motivation

    1.2 Everyday Examples

    1.3 Definition

    Page 1 of 1Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro.html

  • 8/13/2019 Group19 Semaphore

    5/68

    [ Previous: 0. What Is This Website All About? | Up: 1. Introduction | Next: 1.2.

    Everyday Examples ]

    1.1 MotivationIn the olden days, semaphores were basically physical devices with colored

    lights and arms to signal the drivers of trains to prevent crashing from each

    other or to send complex messages by sailors at night by opening and closingthe shutters of the lantern that they used. Thus these semaphores were devices

    to prevent mutual exclusion (two things cannot happen at the same time)

    happening in real life. So why the need for semaphores when people were

    happy signaling one another to get the job done? Well like so many things

    today, it all started in the swinging sixties.

    The 1960s was a time of dynamic and radical, social, political and technological

    change. The era was marked with the birth of the hippies, gay and feminist

    movements in USA, opposition to the Vietnam war, rapid rise of the New left,

    rampant drug use, the ever growing hostile cold war, and the period also a

    marked a very important contribution to computer science. People had a race

    for using computers, and the processors had to restrict their access to shared

    resources. This gave rise to the problem of mutual exclusion in the computing

    environment. Edsger Dijkstra , found a new way of tackling this problem by

    involving semaphores. His semaphore was not a physical device but a variable

    which can be accessed by different operations. In his paper on THE , the system

    which implemented the idea of semaphores from a software perspective, for the

    first time, he had mentioned that one of the main motivations for the use of

    semaphores was to reduce the complexity involved when it came to

    programming which dealt with mutual exclusion.

    Page 1 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro_motivation.html

  • 8/13/2019 Group19 Semaphore

    6/68

    You would be surprised at the penetration level of semaphores. You can find

    their use from libraries to aviation systems. The next section illustrates different

    cases in which semaphores are used.

    [ Previous: 0. What Is This Website All About? | Up: 1. Introduction | Next: 1.2.

    Everyday Examples ]

    Page 2 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro_motivation.html

  • 8/13/2019 Group19 Semaphore

    7/68

    [ Previous: 1.1 Motivation | Up: 1. Introduction | Next: 1.3. Definition ]

    1.2 Everyday ExamplesEarlier we had a look at the train, which uses the concept of semaphores. The

    following examples would illustrate the same, however, although, they may

    seem similar, the technicalities involved are different. We would have a look at

    the beautiful and intricate world of it in the implementation. For now contentyourself with the elegant simplicity of the idea, that has helped resolve a lot of

    otherwise major barriers.

    This particular example looks at the implementation of semaphores in a library.

    Scenario : Consider a situation where students reading CS2106 decide touse the book Modern Operating Systems as their main reference just

    before their final exam. But alas there is only one copy of it in thelibrary and unfortunately NUS is going through a major maintenance inits library website at that time, so no electronic helps to check whetherthe book is available.

    Problem : How is it possible for a student to check the availability of abook, without having to physically climb up or down the stairs, into thedungeon of books, and getting disappointed? You would hate having to dothat, wont you?

    Solution : A very bright lad/lass doing the course suggested the followingin which the information desk, where the librarian sits would be used as aflag, to inform the students on the books status:

    1. The librarian first makes a list of people who want the book on afirst come first served basis. She also sets the available status ofthe book for others to see on a slate. If the available status is 1

    Page 1 of 3Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro_examples.html

  • 8/13/2019 Group19 Semaphore

    8/68

    Here the available information that is given to other students about the status

    of the book acts like a semaphore. The slate acts as the signal to students.

    The next example ought to get you a bit interested in semaphores, or at least

    appreciate it more. Trust us on this, you would want to read, your future

    investments and millions depend on this.

    then the book is available and if its 0, book is not available.

    2. The first student comes to borrow the book.

    3. He sees that the book is available from the slate, as thelibrarians list is empty initially.

    4. He checks out the book and on the slate he sets available=0 toinform others.

    5. Now a second student who wants to use the book would check thestatus from the slate.

    6. He finds that the book is not available so the librarian enters his

    name in her list.

    7. Now the first student who borrowed it earlier finishes using thebook, he returns the book and then immediately changes theavailable status of the book to 1.

    Hence the second student who is next in the librarians list can nowaccess the book and he repeats the above process.

    Scenario: Consider a case where Angelina Jolie has a million dollars in heraccount and she now wants to deposit another million dollars. At the same

    time Brad Pitt wants to withdraw a million dollars from Jolies account.Both are trying to access the same account at the same time fromdifferent ATMs. There are two possibilities:

    1. If Jolies request is processed first, then the balance in heraccount is updated to 2 million dollars. Then Brads request is

    Page 2 of 3Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro_examples.html

  • 8/13/2019 Group19 Semaphore

    9/68

    What was the problem here? Well two processes, i.e. Brad and Jolie, both

    having access to the same account, at the same time, i.e, mutual exclusion.

    So what is the solution, well the answer to that lies in the next section.

    [ Previous: 1.1 Motivation | Up: 1. Introduction | Next: 1.3. Definition ]

    processed 1 million is deducted and now the balance again becomesto 1 million dollars.

    2. If Brads request is processed first, then the balance in Joliesaccount is deducted to 0 dollars. Then Jolies request is processedand now the balance becomes to 1 million dollars.

    Here we can see that there is competition for using the Bankdatabase (storage) and the result depends on which request isprocessed first. But both of them give out the correct result, i.e.one million dollars.

    Problem : Consider that these events happen alternatively:

    1. Jolie tries to deposit 1 million dollars. The system downloads theprevious account balance (i.e. 1 million) from the bank database andadds the deposit amount, i.e. another one million dollars.

    2. But before updating the bank balance the system starts handlingBrads request of withdrawing 1 million dollars.

    3. Now again the system downloads the previous account balance(i.e.1 million) from the bank database and deducts the withdrawal

    amount.

    First the system handles Jolies request to update her accountbalance to 2 million dollars (1 million + 1 million).

    Now the system handles Brads request to update Jolies account to0 dollars (1 million - 1 million).

    Final result: Angelina Jolie is left with 0 dollars!!!

    Page 3 of 3Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro_examples.html

  • 8/13/2019 Group19 Semaphore

    10/68

    [ Previous: 1.2 Everday Examples | Up: 1. Introduction | Next: 2. Implementation ]

    1.3 DefinitionA semaphore is:

    1. A hardware or software flag used to indicate the status of some activity.

    2. A shared space for inter-process communications (IPC) controlled by "wake up" and

    "sleep" commands. The source process fills a queue and goes to sleep until the

    destination process uses the data and tells the source process to wake up.

    Dijkstra introduced semaphore, S, with two operations, V and P. V(S) increases the value of

    S by 1 in an atomic (or indivisible) operation and may wake one of the waiting processes up.

    P(S) checks the value of S. If S is greater than 0, P(S) decreases the value of S by 1 in an

    atomic operation. Otherwise, the calling process goes to sleep and waits until S is greater

    than 0. In addition, there is an operation which takes a parameter and initializes a

    semaphore to that value.

    The following example illustrates a scenario where the problem of sharing one printer (I/O)

    is resolved using semaphore. (In this case, we assume the printer does not have a queue for

    print jobs.) Please click START to begin.

    Page 1 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro_definition.html

  • 8/13/2019 Group19 Semaphore

    11/68

    If a semaphore only takes two values, 0 and 1, it is called a mutex. In this case, a binary

    semaphore or mutex, is always initialized to 1.

    And, now that we have got ourselves acquainted with semaphores, strap your seatbelts, for

    we are going to take you on a fun filled journey of verhoog and probeer. Sounds like cheese

    doesnt it? Well you are in for a surprise.

    [ Previous: 1.2 Everday Examples | Up: 1. Introduction | Next: 2. Implementation ]

    Page 2 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/intro_definition.html

  • 8/13/2019 Group19 Semaphore

    12/68

    [ Previous: 1.3. Definition | Up: Site Map | Next: 2.1. Implementation of

    Semaphores ]

    2. Implementation2.1 Implementation of Semaphores

    2.2 Classical Problems

    2.2.1 Sleeping Barber 2.2.2 Cigarette Smokers

    2.2.3 Unisex Bathroom

    2.3 POSIX Library

    2.3.1 POSIX Mutexes

    2.3.2 POSIX Semaphores

    2.4 Case Study on Prex Semaphore

    Page 1 of 1Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation.html

  • 8/13/2019 Group19 Semaphore

    13/68

    [ Previous: 1.3 Definition | Up: 2. Implementation | Next: 2.2 Classical Problems ]

    2.1 Implementation of SemaphoresAs mentioned in the previous section, there are two operations on a semaphore,

    P and V, plus an operation to initialize a semaphore. P and V can also be

    referred to as increment and decrement , or signal and wait . (It is interesting to

    note that there is no operation to read the value of a semaphore. Therefore,before we perform the P operation, we would not know whether the calling

    process will block or not.) The code for these operations is shown below.

    P and V must be atomic, or indivisible, operations. In particular, when s is

    greater than 0, the decrement of s must follow immediately, i.e. no process can

    be interleaved beween the test s > 0 and the decrement. All of these can be

    done using the test-and-set instruction or ignoring interrupts. The test-and-set

    instruction checks the value of a memory location and writes to it if some

    condition is satisfied; all in an atomic operation. If this instruction is not

    supported, ignoring interrupts can be used to ensure no other processes can

    run while P or V is being executed.

    init(s, value):s = value

    P(s):// the calling process may go to sleep if s 0s--

    V(s):s++// may wake one of the waiting processes up

    Page 1 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_semaphores.html

  • 8/13/2019 Group19 Semaphore

    14/68

    The P operation may invovle busy waiting if it is implemented as a loop

    continously checking the condition s > 0 . In this case, the operation wastes the

    processor time. One way to avoid this problem is to maintain a queue of

    processes waiting on each semaphore. If the queue is a FIFO queue, the

    processes are waken up in the order they are put into the queue. Otherwise, wemight not be able to tell which process will be waken up by the V operation. The

    code for the implementation with queuing is shown below.

    It is interesting to note that in this case, the value of the semaphore can be

    negative, which is impossible for the code shown at the beginning of thissection. A value of -n (n > 0) implies there are n processes waiting on the

    semaphore. s is initialized to 1 to ensure the first process can enters its critical

    section.

    Finally, mutex is a binary semaphore. The idea of mutex is mutual exclusion, i.e.

    only one process can be in the critical section at one time. On the other hand, a

    semaphore can have a value greater than one. For example, we may allow a

    certain number of connections in a database system and thus initialize the

    semaphore to the maximum number of connections allowed.

    Spinlocks

    Besides Test and Set instructions we also can use another synchronization

    s = init(1) // s is initialized to 1

    P(s):s--if s < 0:

    the process goes to sleepand is put into the queue waiting for thissemaphore

    V(s):if s < 0: // if the queue is not empty

    remove one process from the queue and wake it ups++

    Page 2 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_semaphores.html

  • 8/13/2019 Group19 Semaphore

    15/68

    mechanism called Spinlocks which makes a process simply wait in a loop until

    the lock becomes available. Because sometimes it is much efficient to

    constantly poll for the availability of a lock rather than

    Pre-empting the thread, schedule another thread.

    Keeping track of which process owns the synchronization object or lock,

    or how long has the timeout interval elapsed.

    The additional usage of C function calls or even of Assembler routines for

    a fair first-in-first-out mechanism.

    The pseudo code for implementing Spinlocks is as follows:

    The disadvantage of using spinlocks is that, since it involves busy waiting, a lot

    of CPU time is devoted to it. So these spinlocks are efficient only if the

    processes are likely to be blocked for a short period of time. Moreover they are

    certainly unfair as there is no mechanism involved in them to prevent a situation

    of starvation where a process might just have to wait forever.

    References 1. Semaphores (Wikipedia)

    2. Process Synchronization: Semaphores

    3. Allen B. Downey (2005), The Little Book of Semaphores

    4. Spinlocks and Semaphores

    typedef int SpinLock;

    void InitLock(SpinLock *L){ *L = 0; }

    void Lock(SpinLock *L){ while (TestAndSet(L))

    ;}

    void UnLock(SpinLock *L)

    { *L = 0; }

    Page 3 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_semaphores.html

  • 8/13/2019 Group19 Semaphore

    16/68

    5. Spinlock (Wikipedia)

    6. User-Level Spin Locks

    [ Previous: 1.3 Definition | Up: 2. Implementation | Next: 2.2 Classical Problems ]

    Page 4 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_semaphores.html

  • 8/13/2019 Group19 Semaphore

    17/68

    [ Previous: 2.1 Implementation of Semaphores | Up: 2. Implementation | Next:

    2.2.1 Sleeping Barber Problem ]

    2.2 Classical Problems2.2.1 Sleeping Barber

    2.2.2 Cigarette Smokers

    2.2.3 Unisex Bathroom

    Page 1 of 1Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_problems.html

  • 8/13/2019 Group19 Semaphore

    18/68

    [ Previous: 2.1 Implementation of Semaphores | Up: 2.2 Classical Problems | Next: 2.2.2Cigarette Smokers ]

    2.2.1 Sleeping BarberScenario

    Consider a barbers shop where there is only one barber, one barber chair and a number of

    waiting chairs for the customers. When there are no customers the barber sits on the barber

    chair and sleeps. When a customer arrives he awakes the barber or waits in one of thevacant chairs if the barber is cutting someone elses hair. When all the chairs are full, the

    newly arrived customer simply leaves.

    Problems

    There might be a scenario in which the customer ends up waiting on a barber and a

    barber waiting on the customer, which would result to a deadlock.

    Then there might also be a case of starvation when the customers dont follow an

    order to cut hair, as some people wont get a hair cut even though they had been

    waiting long.

    Use of Semaphores

    The solution to these problems involves the use of three semaphores out of which one is a

    mutex (binary semaphore). They are:

    Customers : Helps count the waiting customers.

    Barber : To check the status of the barber, if he is idle or not.

    accessSeats : A mutex which allows the customers to get exclusive access to the

    number of free seats and allows them to increase or decrease the number.

    NumberOfFreeSeats : To keep the count of the available seats, so that the customer

    can either decide to wait if there is a seat free or leave if there are none.

    The Procedure

    Page 1 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_barber.html

  • 8/13/2019 Group19 Semaphore

    19/68

    When the barber first comes to the shop, he looks out for any customers i.e. calls P

    (Customers) , if there are none he goes to sleep.

    Now when a customer arrives, the customer tries to get access to the accessSeats

    mutex i.e. he calls P(accessSeats) , thereby setting a lock.

    If no free seat (barber chair and waiting chairs) is available he releases the lock i.e.

    does a V(accessSeats) and leaves the shop.

    If there is a free seat he first decreases the number of free seats by one and he calls V

    (Customers) to notify the barber that he wants to cut.

    Then the customer releases the lock on the accessSeats mutex by calling V

    (accessSeats) .

    Meanwhile when V(Customers) was called the barber awakes.

    The barber locks the accessSeats mutex as he wants to increase the number of free

    seats available, as the just arrived customer may sit on the barbers chair if that is free.

    Now the barber releases the lock on the accessSeats mutex so that other customers

    can access it to the see the status of the free seats.

    The barber now calls a V(Barber) , i.e. he tells the customer that he is available to cut.

    The customer now calls a P(Barber) , i.e. he tries to get exclusive access of the barber

    to cut his hair.

    The customer gets a haircut from the barber and as soon as he is done, the barber

    goes back to sleep if there are no customers or waits for the next customer to alert

    him.

    When another customer arrives, he repeats the above procedure again.

    If the barber is busy then the customer decides to wait on one of the free waiting seats.

    If there are no customers, then the barber goes back to sleep.

    Implementation

    The following pseudo-code guarantees synchronization between barber and customer and

    is deadlock free, but may lead to starvation of a customer.

    The Barber (Thread/Process)

    Customers = init(0)Barber = init(0)accessSeats = init(1) // mutex

    NumberOfFreeSeats = N //total number of seats

    Page 2 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_barber.html

  • 8/13/2019 Group19 Semaphore

    20/68

    The Customer (Thread/Process)

    Note: The solution can be modified so that the customers are made to form a queue as they

    arrive so that the barber can service these customers on a first come first served basis. This

    solves the problem of starvation where in a customer might have to wait long for his turn to

    come.

    while (true) { // runs in an infinite loop

    P(Customers) // tries to acquire a customer - if none isavailable

    he goes to sleep

    P(accessSeats) // at this time he has been awaken - want to

    modify the number of available seats

    NumberOfFreeSeats++ // one chair gets free

    V(Barber) // the barber is ready to cut

    V(accessSeats) // we don't need the lock on the chairsanymore

    // here the barber is cutting hair

    }

    P(accessSeats) // tries to get access to the chairs

    if (NumberOfFreeSeats > 0) { // if there are any free seats

    NumberOfFreeSeats-- // sitting down on a chair

    V(Customers) // notify the barber, that there is a customerwaiting

    V(accessSeats) // don't need to lock the chairs anymore

    P(Barber) // now it's this customers turn, but wait if the barber is busy

    // here the customer is having his hair cut

    } else { // there are no free seats

    // tough luck

    V(accessSeats) // but don't forget to release the lock on theseats

    // customer leaves without a haircut}

    Page 3 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_barber.html

  • 8/13/2019 Group19 Semaphore

    21/68

    Animation

    Please click START to begin.

    References 1. Sleeping Barber Problem (Wikipedia)

    [ Previous: 2.1 Implementation of Semaphores | Up: 2.2 Classical Problems | Next: 2.2.2

    Cigarette Smokers ]

    Page 4 of 4Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_barber.html

  • 8/13/2019 Group19 Semaphore

    22/68

    [ Previous: 2.2.1 Sleeping Barber | Up: 2.2 Classical Problems | Next: 2.2.3

    Unisex Bathroom ]

    2.2.2 Cigarette SmokersProblem

    The cigarette smokers problem was first presented by Suhas Patil in 1971.

    There are three smokers and one agent. A cigarette is made of three

    ingredients: tobacco, paper and match. Each smoker has infinite supply of one

    ingredient, e.g. the first one has infinite supply of tobacco, the second one has

    infinite supply of paper and the last one has infinite of match. The agent has

    infinite supply of all ingredients. The agent repeatedly chooses two ingredients

    at random and puts them on the table, and the smoker who has the

    complementary ingredient can take the two ingredients and make a cigarette to

    smoke. For example, if the agent puts tobacco and paper on the table, the

    smoker who has infinite supply of match can make a cigarette. In this problem,

    the agent represents the operating system and the smokers represent the

    processes. The operating system should allocate the required resources to the

    processes and, at the same time, avoid deadlock.

    We will look at different versions of this problem.

    Patil's Version

    There are two restrictions on the solution:

    The agent code cannot be modified

    Conditional statements and arrays of semaphores are not allowed

    Page 1 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    23/68

    With these restrictions, this problem is unsolvable. The Patil's version is also

    called the impossible version. However, while the first restriction makes sense

    because the operating system's code should not be modified every time we

    need to solve a problem, the second restriction is not reasonable, according to

    David Parnas. He called such restriction "artificial" and said that artificialrestrictions make many problems unsolvable.

    The Trivial Version

    In this version, the agent signals the smoker who has the complementary

    ingredients after putting the two ingredients on the table. This version can be

    solved quite easily.

    Initialization

    The agent code

    agentSemaphore = init(1) // the semaphore for the agent,initialized to 1

    for s in smokerSemaphores: // smokerSemaphores is anarray of three semaphores

    // for three smokers

    s = init(1) // all the three semaphores areinitialized to 1

    while (1):P(agentSemaphore)

    i, j = chooseIngredients() // choose two ingredients

    at random putOnTable(i, j)

    u = findComplimentarySmoker(i, j) // the smoker whohas the

    // complimentaryingredient

    Page 2 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    24/68

    The code for the first smoker is presented below. The codes for other smokers

    are similar.

    The smoker takes the two ingredients on the table, makes a cigarette and wakes

    up the agent by calling V(agentSemaphore) . While this smoker is smoking, the

    agent continues to put two ingredients on the table. If these ingredients aredifferent from the last two, the agent can wake up another smoker. Otherwise,

    the smoker who is smoking can make another cigarette after he has finished

    smoking.

    In summary, this version is easy to solve because the agent knows who to

    signal. However, this may not be the case in practice because the operating

    system may not know the required resources of the processes before hand. We

    will consider a more interesting version.

    The Interesting Version

    This version only keeps the first restriction of the Patil's version, which is the

    agent code cannot be modified.

    The agent uses four semaphores as follows:

    V(smokerSemaphores[u])

    while (1):P(smokerSemaphores[0])

    makeCigarette() V(agentSemaphore)

    smoke()

    agentSemaphore = init(1) // the semaphore for the agent

    tobaccoSemaphore = init(0) // the semaphore for tobaccoon the table

    paperSemaphore = init(0) // the semaphore for paper onthe table

    Page 3 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    25/68

    The agent uses three threads, each of which is for putting two ingredients on

    the table. When V(agentSemaphore) is called, one of the threads will wake up

    and put two ingredients on the table. The code for the thread which puts

    tobacco and paper on the table is presented below. The codes for other threads

    are similar.

    A Non-Solution

    Consider the following codes for the three smokers.

    matchSemaphore = init(0) // the semaphore for match onthe table

    while (1):P(agentSemaphore)

    V(tobaccoSemaphore)

    V(paperSemaphore)

    while (1): // this smoker has infinite supply of matchP(tobaccoSemaphore)P(paperSemaphore)

    makeCigarette() V(agentSemaphore)

    smoke()

    while (1): // this smoker has infinite supply of paperP(tobaccoSemaphore)P(matchSemaphore)

    makeCigarette() V(agentSemaphore)

    smoke()

    while (1): // this smoker has infinite supply of tobaccoP(paperSemaphore)P(matchSemaphore)

    makeCigarette() V(agentSemaphore)

    smoke()

    Page 4 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    26/68

    This is a non-solution because deadlock can occur. Suppose one agent thread

    puts tobacco and paper on the table. The smoker with infinite supply of match is

    blocking on tobacco so he can pick tobacco up. At the same time, the smoker

    with infinite supply of tobacco is blocking on paper so he can pick paper up.

    Now the first smoker blocks on paper and the second smoker blocks on match.This is a deadlock. For comparison with the dining philosophers problem, this

    is similar to the case where all the philosophers pick up the left forks and block

    on the right forks.

    A Solution

    The solution below is similar to David Parnas' solution. Parnas' codes are more

    complex in order to avoid conditional statements.

    Initialization

    This solution uses three threads called pushers to signal the smokers with the

    isTobacco = false // tobacco is not on the table

    isPaper = false // paper is not on the table

    isMatch = false // match is not on the table

    tobaccoSmokerSemaphore = init(0) // the semaphore for thesmoker with

    // infinite supply oftobacco

    paperSmokerSemaphore = init(0) // the semaphore for thesmoker with

    // infinite supply of paper

    matchSmokerSemaphore = init(0) // the semaphore for thesmoker with

    // infinite supply of match

    mutex = init(1) // the mutex used in the codes below

    Page 5 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    27/68

    complementary ingredient. The code for one pusher is presented below. The

    codes for the other two pushers are similar.

    The code for one smoker is presented below. The codes for other smokers are

    similar.

    This pusher wakes up after one of the agent threads put tobacco on the table. If

    isPaper or isMatch is true, paper or match is on the table and has been

    "intercepted" (to be explained later) by one of the other two pushers. Therefore,

    this pusher can wake either the match smoker or the paper smoker up. If neither

    isPaper nor isMatch is true, paper or match is on the table (because there are

    two ingredients on the table and the first one is tobacco) but not yet"intercepted" by one of the other two pushers. In this case, this pusher set

    isTobacco to true so that any pusher who runs later will know that tobacco has

    been "intercepted". The mutex is used to ensure only one pusher enters the

    critical section at one time.

    // this semaphore is introduced in the non-solution agentthread

    P(tobaccoSemaphore)

    P(mutex)

    if isPaper:isPaper = false

    V(matchSmokerSemaphore)else if isMatch:

    isMatch = false V(paperSmokerSemaphore)

    else:

    isTobacco = true V(mutex)

    P(matchSmokerSemaphore) makeCigarette() V(agentSemaphore)

    smoke()

    Page 6 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    28/68

    The pushers can be seen as a processing unit which responds to the agent (or

    the available ingredients) by signaling the appropriate smoker. This is what we

    mean by "intercept" in the above paragraph. Moreover, isTobacco and

    tobaccoSemaphore are slightly different. isTobacco indicates whether tobacco

    has been "intercepted" while tobaccoSemaphore indicates whether tobacco ison the table. An ingredient can be on the table and not yet "intercepted" by the

    pushers.

    By using the pushers, we have separated the signal code from the agent.

    Compared to the agent in the trivial solution, which does both putting

    ingredients and signaling the smokers, this is more modular programming

    because the agent does one task and the pushers do one task. Later if the

    problem statement changes slightly, we only have to modify the pushers code.

    Thus, the restriction of not modifying the agent code is satisfied.

    The Generalized Version

    This version is suggested by Parnas where the agent does not wait for the

    smokers. That means the agent repeatedly puts the ingredients and there can

    be multiple instances of one ingredient on the table. How do we modify thesolution to solve this generalized problem?

    We replace boolean variables by integers to keep track of the number of

    instances of each ingredient.

    The pusher code is modified accordingly.

    nTobacco = 0nPaper = 0nMatch = 0

    P(tobaccoSemaphore)P(mutex)if nPaper > 0:

    nPaper--

    Page 7 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    29/68

    Interestingly, in this case, the values of tobaccoSemaphore , paperSemaphore

    and matchSemaphore can go beyond 1, and that is absolutely fine. nTobacco is

    the number of "intercepted" but not yet combined with other ingredients while

    tobaccoSemaphore indicates the total number of instances of tobacco on the

    table. Each time a pusher enters the critical section, it looks for combinations of

    two ingredients. If there is such a combination, it signals the appropriate

    smoker. Otherwise, it just increases the number of "intercepted" instances of

    the corresponding ingredient.

    References 1. Allen B. Downey (2005), The Little Book of Semaphores

    2. Cigarette Smokers Problem (Wikipedia)

    [ Previous: 2.2.1 Sleeping Barber | Up: 2.2 Classical Problems | Next: 2.2.3Unisex Bathroom ]

    V(matchSmokerSemaphore)else if isMatch > 0:

    nMatch-- V(paperSmokerSemaphore)

    else:nTobacco++

    V(mutex)

    Page 8 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_smokers.html

  • 8/13/2019 Group19 Semaphore

    30/68

    [ Previous: 2.2.2 Cigarette Smokers | Up: 2.2 Classical Problems | Next: 2.3

    POSIX Library ]

    2.2.3 Unisex BathroomScenario

    Have u visited the SOC1 building recently? Not much has changed in the

    physical structure since SOC relocated to COM1, but a refresher to everyone,

    there is only one female washroom on the 8th floor. So for all you guys, who get

    very annoyed that you have to go all the way down to the 3rd floor to use the

    common room, well SOC, gratefully, has come up with a solution; UNISEX

    common room!!

    Readers are we getting ideas?

    Geek 1 : Woah!!! Awesome, finally SoC is rocking it.Geek 2 : Yeah lor, we become SCHOOL OF COOLS .

    Did it invoke thoughts of perhaps arranging a meeting with a specialsomeone, when you are up all night coding?

    Or did your creative side get the better of you, and you commencedplanning on an intricate, artistic and clever plan to get someone to notice

    you?

    Page 1 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    31/68

    Take our advice, pause all those thoughts!!

    Yeah well, I was equally disappointed.

    We are not in the school of computing for no reason. The smart professors at

    SOC have devised a devious plan, such that people from the opposite sex can

    not use the washroom at same time.

    So to put things in perspective we have the following situation:

    There cannot be men and women at the same time in the bathroom.

    There are n number of cubicles.

    As students of CS2106, you would realize that the problem could be sorted out,

    with the aid of semaphores. But potential problems that could arise are

    deadlock and starvation. Well we would deal with that in time. For now, lets get

    started by trying to prevent members of the opposite sex to mingle in the

    common room.

    Solution

    Semaphores

    Bathroom is the shared resource

    Which would eventually lead to something like this?

    Geek 1 : Wah wah, what and why??Geek 2 : Yeah, why? I was in such a nice place, a natural high. :(

    Geek 1 & Geek 2 : (Wailing)!!

    Page 2 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    32/68

    Male and Females would acts as threads

    Problems

    Problems that arise as a result of the implementation of this protocol are:

    Deadlock This situation would arise, when all individuals who waiting to

    use the common room, never get to. This could arise as result of improper

    software implementation of the semaphores. Theoretically, since there are

    n(at least 1) cubicles, one person would get to use it, and deadlock would

    not occur.

    Denial/Starvation Since its a condition that we have one party being

    denied the access of resources. In this case the resource being thewashroom. For example, we could have a situation, where there a whole

    line of women and just one man, waiting to use the common room. In this

    case, women would always be using up the n cubicles, and it would take a

    very long time before the gent would get an opportunity, because he would

    be unable to use it unless all n cubicles are free, due the no gender mixing

    policy.

    Use of Semaphores

    The solution involves the use of semaphores as mentioned earlier.

    Let us assume that there are 3 cubicles, i.e n = 3

    femaleMultiplex this semaphore would be initialized to 3 (n). This would

    control the number of women in (making sure not more than 3).

    maleMultiplex similar function as for the femaleMultiplex , whoeverapplicable to males

    Empty is a mutex, it is 1 if room empty, 0 otherwise

    nextInLine is a mutex, if the sex of the person is different from the

    group/person inside it is 0, 1 otherwise

    maleSwitch LightSwitch() allows men to bar women from the room. When

    Page 3 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    33/68

    the first male enters, the lightswitch locks empty , barring women; When

    the last male exits, it unlocks empty , allowing women to enter

    femaleSwitch LightSwitch() , Women do likewise using the same

    Procedure #1 (Non-Solution)

    When a person (assume female) arrives, and if there is no one in the

    bathroom, she would be allowed to enter.

    At this point femaleSwitch.lock(empty) would be called. This would bar

    men from accessing the bathroom.

    Then femaleMultiplex.wait() or P() would be called to decrease the

    semaphore of the females. (At wait(), it checks if there are vacancies, and

    only if there are any it proceeds.)

    If the bathroom is operating at maximum capacity then the female thread

    would wait until a vacancy opens up!

    Once the female (thread) is ready to leave, the thread would first increment

    the value in the femaleMultiplex semaphore, by calling

    femaleMultiplex.signal() or V().

    Now suppose, another female in queue wanted to enter, the thread too

    would follow the same steps as above.

    When the number of femaleMultiplex is 3 (n), that implies the bathroom is

    empty, at which point, femalSwitch.unlock(empty) is carried out. Every

    thread reads femaleSwtich.unlock(empty) , however, it is unlocked only

    when the semaphore value is equal to maximum number of cubicles.

    (Although in theory, there is no operation to get the value of a semaphore,

    the library for semaphore implementation may have such a function. Even

    if it is not available, we can use a simple counter to keep track of the

    semaphore value manually.)

    This would notify that the bathroom is empty and would not bar men from

    entering.

    The pseudo code for the above, female version (similar version for males, using

    Page 4 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    34/68

    male variables) is as follows:

    The problem with above solution is that the situation could go into a state of

    starvation. That is there could be a long line of females, and just one man,

    waiting. In which, case the male would not get a chance for a very long and

    unfair period of time, even though he might have been there before many

    females. This is because, in the above code we check the gender of the people

    in the bathroom, and allow a maximum number of individuals of the particularsex to go in until the bathroom is completely empty.

    So, a solution to the above problem is implementing nextInLine . This would

    check who is in queue next and would bar the thread if it is of the opposite

    nature the thread currently being processed.

    nextInLine is a mutex, if the sex of the person (the thread) is different from the

    group/person inside it is 0, 1 otherwise.

    Procedure #2 (Solution)

    We have a nextInLine mutex, which would check the incoming thread, i.e it

    would perform a nextInLine.wait()

    And bar a thread of the different nature to what is being currently

    processed.

    For example: suppose the room is currently with males, but next thread if

    female. Then nextInLine would block the female thread, and wait until all

    male threads have finished. Then the female thread would be allowed to

    enter.

    After the female thread gets through nextInLine.wait() (which means the

    femaleSwitch.lock(empty)femaleMultiplex.wait()# bathroom code herefemaleMultiplex.signal()femaleSwitch.unlock(empty)

    Page 5 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    35/68

    female enters the bathroom), the thread would call femaleSwitch.lock

    (empty) , which bars males from entering.

    When exiting after using the bathroom (thread executes respective code),

    in the case where a female thread is waiting on existing male threads to

    finish utilizing the resource, the maleSwitch.unlock(empty) would checkthe male semaphore variable to ensure its equal to 3 (n number of

    cubicles), and signal that the bathroom is empty.

    Women would be allowed to enter to n capacity (as in procedure 1), until

    the next male arrives. Then the process repeats itself.

    So in this manner starvation would be avoided. This procedure may not be

    efficient. This system could perhaps be implemented in a system with several

    hundred threads. If there is a frequent change in the type (gender) of thread,

    then it would be blocked and hence barring additional threads.

    The pseudo code for the above procedure (for the male thread) is:

    Procedure #3 (Efficiency vs Fairness)

    The following solution is what we think can be an improvement in efficiency

    over the previous one.

    We could implement 2 queues, one for males and the other for females.

    Queuing numbers are given to each thread that arrives on a first come first

    serve basis.

    That is, in queue F (female), I could have numbers 1, 2, 4-10. And in queue

    nextInLine.wait() maleSwitch.lock(empty)

    nextInLine.signal()

    maleMultiplex.wait()# bathroom code here

    maleMultiplex.signal()

    maleSwitch.unlock(empty)

    Page 6 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    36/68

    M (male), numbers 3, 8, 11.

    Suppose initially the bathroom is empty. So the first thread is a female,

    therefore, females would be allowed to enter to maximum capacity, in this

    case 3.

    Now when reading sequence numbers, since it is sequential (successor is+1 of the predecessor), there would be a hiccup after 2 in the female

    queue, as 3 is not there. This would mean that there are males waiting.

    However, instead of just letting 1 & 2 to enter, and then swapping to 3

    (male queue) as would have been done in procedure 2, it is noted that a

    jump in sequence number has occurred, which is a sign to visit the male

    queue.

    Three (maximum capacity of bathroom) females would be allowed to enter,i.e. 1, 2 & 4. Then female threads are barred. The male thread 3 would be

    blocked.

    Once the threads 1, 2 & 4 have finished, thread 3 would be allowed to

    enter.

    Here again after 3, there is a jump, it is noted. Therefore, it would permit

    the next 2 in queue to enter, and then bar further male threads.

    Once again, we would swap to the female queue.

    The above procedure minimizes the number of swapping, as compared to

    procedure 2. It ensures that the bathroom always runs at full capacity, for either

    of the sex as long as there are people in the queue. Although threads are not

    entered in sequence order, it is obvious that the efficiency offsets the slight

    unfairness.

    The pseudo code is similar to procedure 2:

    // nextInLine checks for sequence number, in addition. Ifa jump is noted, it would adjust a variable, say unfair =(n - currentlyInside). Hence, that many from the currentqueue would be allowed, before being barred. After unfairamount have entered, the threads from the other queuewould be allowed to enter.

    Page 7 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    37/68

    References 1. Allen B. Downey (2005), The Little Book of Semaphores

    2. David J. Powers (2006), The Unisex Bathroom: Fairness versus Performance

    [ Previous: 2.2.2 Cigarette Smokers | Up: 2.2 Classical Problems | Next: 2.3

    POSIX Library ]

    nextInLine.wait() // checks for sequence number, inaddition

    maleSwitch.lock(empty)nextInLine.signal()

    maleMultiplex.wait()# bathroom code here maleMultiplex.signal()

    maleSwitch.unlock(empty)

    Page 8 of 8Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/implementation_bathroom.html

  • 8/13/2019 Group19 Semaphore

    38/68

    [ Previous: 2.2.3 Unisex Bathroom | Up: 2. Implementation | Next: 2.3.1 POSIX

    Mutexes ]

    2.3 POSIX LibraryPOSIX or "Portable Operating System Interface" is the collective name of a

    family of related standards specified by the IEEE to define the application

    programming interface (API) for software compatible with variants of the Unixoperating system. (Wikipedia)

    2.3.1 POSIX Mutexes

    2.3.2 POSIX Semaphores

    Page 1 of 1Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix.html

  • 8/13/2019 Group19 Semaphore

    39/68

    [ Previous: 2.2.3 Unisex Bathroom | Up: 2.3 POSIX Library | Next: 2.3.2 POSIX

    Semaphores ]

    2.3.1 POSIX MutexesThe following declarations show the POSIX API for threads involving mutex:

    #include - the header file containing the relevant functions

    int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t

    *mutexattr) used to initialize the mutex

    int pthread_mutex_lock(pthread_mutex_t *mutex) used to lock a mutex

    so only one thread has exclusive access

    int pthread_mutex_unlock(pthread_mutex_ t *mutex) used to unlock a

    mutex so that other threads can access the mutex

    int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -

    makes the current thread wait until the specified condition is true

    int pthread_cond_signal(pthread_cond_t *cond) signals a waiting a

    thread when the specified condition becomes false

    Heres a program which illustrates the simple use of the pthread_cond_wait

    system call mentioned above

    There are two threads created here which uses two functions,

    functionAdd1 and functionAdd2 and three constant values DONE=10 ,

    STOP1=2 and STOP2=4 which is used for checking conditions.

    A variable sum is shared by both the threads.

    The functionAdd1 increments and prints the value of sum until the value of

    sum is equal to 2 and then it is made to wait by the pthread_cond_wait

    Page 1 of 6Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_mutexes.html

  • 8/13/2019 Group19 Semaphore

    40/68

    system call.

    Now functionAdd2 is given the access to the variable sum and it

    increments and prints the value of sum until the condition inside it

    becomes false, after which it signals functionAdd1 to proceed.

    Finally the program ends when the sum value is greater than or equal to10.

    #include

    #include

    #include

    pthread_mutex_t sum_mutex = PTHREAD_MUTEX_INITIALIZER;

    pthread_mutex_t condition_mutex =PTHREAD_MUTEX_INITIALIZER;

    pthread_cond_t condition_cond = PTHREAD_COND_INITIALIZER;

    void *functionAdd1();void *functionAdd2();

    int sum = 0;#define DONE 10

    #define STOP1 2#define STOP2 4int count=0;

    int main(){

    pthread_t thread1, thread2; pthread_create(&thread1, NULL, &functionAdd1, NULL); pthread_create(&thread2, NULL, &functionAdd2, NULL); pthread_join(thread1, NULL); pthread_join(thread2, NULL);

    exit(0);}

    void *functionAdd1(){

    for(;;){

    pthread_mutex_lock(&condition_mutex);while (sum >= STOP1 && sum

  • 8/13/2019 Group19 Semaphore

    41/68

    Let us try to analyze the two functions, functionAdd1 and functionAdd2 .

    functionAdd1

    These lines form the conditional part of the function.

    pthread_cond_wait(&condition_cond,&condition_mutex);

    } pthread_mutex_unlock(&condition_mutex);

    pthread_mutex_lock(&sum_mutex);

    sum++; printf("Sum value functionAdd1: %d\n",sum); pthread_mutex_unlock(&sum_mutex);

    if (sum >= DONE) return (NULL);}

    }

    void *functionAdd2(){

    for(;;){

    pthread_mutex_lock(&condition_mutex);if(sum < STOP1 || sum > STOP2){

    pthread_cond_signal(&condition_cond);}

    pthread_mutex_unlock(&condition_mutex);

    pthread_mutex_lock(&sum_mutex);sum++;

    printf("Sum value functionAdd2: %d\n",sum); pthread_mutex_unlock(&sum_mutex);

    if (sum >=DONE) return (NULL);}

    }

    pthread_mutex_lock(&condition_mutex);while (sum >= STOP1 && sum

  • 8/13/2019 Group19 Semaphore

    42/68

    First the lock mechanism of the mutex is called to provide the thread 1

    with exclusive access of the conditional mutex.

    Then the value of sum is checked to see if its value is >=2 and

  • 8/13/2019 Group19 Semaphore

    43/68

    These lines above check to see if the value of sum is either less than 2 or

    greater than 4.

    If the condition is false then the function continues to increment the

    variable sum and print it out.

    When the condition becomes true, thread2 signals thread1 using the

    system call pthread_cond_signal(&condition_cond) and now thread1 gains

    back access to variable sum .Both the threads stop functioning when the value of sum is >= 10.

    The output:

    From the output we can see that the functionAdd1 was made to wait when the

    value of sum was between 2 and 4 and functionAdd2 increments the value of

    sum and prints it out during that time.

    NOTE: This program was mainly used to explain the working of the

    pthread_cond_wait system call as it might give rise to race conditions because

    the variable sum used in the while loop can't be locked without causing a

    deadlock situation.

    pthread_mutex_lock(&condition_mutex);if(sum < STOP1 || sum > STOP2){

    pthread_cond_signal(&condition_cond);}

    pthread_mutex_unlock(&condition_mutex);

    Sum value functionAdd1: 1Sum value functionAdd1: 2Sum value functionAdd2: 3Sum value functionAdd2: 4

    Sum value functionAdd2: 5Sum value functionAdd2: 6Sum value functionAdd1: 7Sum value functionAdd1: 8Sum value functionAdd1: 9Sum value functionAdd1: 10Sum value functionAdd2: 11

    Page 5 of 6Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_mutexes.html

  • 8/13/2019 Group19 Semaphore

    44/68

    [ Previous: 2.2.3 Unisex Bathroom | Up: 2.3 POSIX Library | Next: 2.3.2 POSIX

    Semaphores ]

    Page 6 of 6Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_mutexes.html

  • 8/13/2019 Group19 Semaphore

    45/68

    [ Previous: 2.3.1 POSIX Mutexes | Up: 2.3 POSIX Library | Next: 2.4 Case Study

    on Prex Semaphore ]

    2.3.2 POSIX SemaphoresThe POSIX semaphore types and functions can be found in .

    Creating a Semaphore

    int sem_init(sem_t *sem, int pshared, unsigned int value);

    Initializes an unnamed semaphore pointed to by sem to value . pshared

    indicates whether the semaphore is shared among processes (if pshared

    is zero, the semaphores is not shared; otherwise it is shared).

    Returns 0 on success and -1 on error

    Example

    sem_t *sem_open(const char *name, int oflag);

    sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int

    value);

    Initializes the named name semaphore to value . oflag is defined by OR'ing

    two values: O_CREAT (to create a semaphore if it does not exist) and

    O_EXCL (to return an error if the semaphore already exists). mode

    specifies the permission of the semaphore.

    Returns the address of the semaphore on success, and SEM_FAILED on

    sem_t sem;sem_init(&sem, 0, 1);

    Page 1 of 7Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_semaphores.html

  • 8/13/2019 Group19 Semaphore

    46/68

    error.

    Example

    Waiting on a Semaphore

    int sem_wait(sem_t *sem);

    int sem_trywait(sem_t *sem);

    int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

    If the value of the semaphore pointed to by sem is greater than 0, sem_wait

    () decreases it by 1 and returns immediately. Otherwise, the process is

    blocked. sem_trywait() is similar to sem_wait() except that if the

    semaphore value is not greater than 0, it returns an error. sem_timedwait()

    specifies a time limit pointed to by abs_timeout . If the decrement cannot

    proceed and time limit expires, the function returns an error.

    All these functions return 0 on success and -1 on error.

    Example

    Incrementing a Semaphore

    int sem_post(sem_t *sem);

    Increments the value of the semaphore pointed to by sem . If the value

    becomes greater than 0, a process may be unblocked.

    // the absolute path to the semaphoreconst char sem_name[] = "/tmp/sem";

    // 0644 is the permission of the semaphoresem_t *sem = sem_open(sem_name, O_CREAT, 0644, 1);

    sem_t sem;...if (sem_wait(&sem) == 0) {

    // do critical stuff}

    Page 2 of 7Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_semaphores.html

  • 8/13/2019 Group19 Semaphore

    47/68

    Returns 0 on success and -1 on error.

    Example

    Getting the Value of a Semaphore

    int sem_getvalue(sem_t *sem, int *sval);

    Gets the value of the semaphore pointed to by sem and places it in the

    location pointed to by sval .Returns 0 on success and -1 on error.

    Example

    Destroying a Semaphore

    int sem_destroy(sem_t *sem);

    Destroys the unnamed semaphore pointed to by sem (only used for

    semaphores initialized by sem_init() ). If there are processes waiting on this

    semaphore or the semaphore has already been destroyed, the function

    may produce undefined behaviour.

    Returns 0 on success and -1 on error.

    Example

    sem_t sem;...

    // do critical stuffsem_post(&sem);

    sem_t sem;...int value;sem_getvalue(&sem, &value);

    sem_t sem;...sem_destroy(&sem);

    Page 3 of 7Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_semaphores.html

  • 8/13/2019 Group19 Semaphore

    48/68

    int sem_close(sem_t *sem);

    Disassociates the named semaphore pointed by sem from the process

    (only used for semaphores created by sem_open() ). The state of the

    semaphore is preserved after it is closed. If the semaphore is reopened, it

    returns to the state when it was closed.

    Returns 0 on success and -1 on error.

    Example

    int sem_unlink(const char *name);

    Removes the named name semaphore. This is used after all the processes

    have closed the semaphore by calling sem_close() .

    Returns 0 on success and -1 on error.

    Example

    Example

    In the following program, we have 3 threads. Each thread needs to enter the

    critical section 3 times, where it sleeps for a random amount of time. We

    initialize the semaphore to 2 so that at most 2 threads can be in the critical

    section at the same time. We can see in the output that this is indeed the case.

    const char sem_name[] = "/tmp/sem";sem_t *sem = sem_open(sem_name, O_CREAT, 0644, 1);...sem_close(sem);

    const char sem_name[] = "/tmp/sem";sem_t *sem = sem_open(sem_name, O_CREAT, 0644, 1);...sem_close(sem);sem_unlink(sem_name);

    #include #include

    Page 4 of 7Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_semaphores.html

  • 8/13/2019 Group19 Semaphore

    49/68

    #include #include #include #include

    void *doSomething1();

    void *doSomething2();void *doSomething3();

    sem_t sem;

    int main() {// initialize semaphore to 2sem_init(&sem, 1, 2);

    pthread_t thread1, thread2, thread3;

    pthread_create(&thread1, NULL, &doSomething1, NULL); pthread_create(&thread2, NULL, &doSomething2, NULL); pthread_create(&thread3, NULL, &doSomething3, NULL);

    pthread_join(thread1, NULL); pthread_join(thread2, NULL); pthread_join(thread3, NULL);

    return 0;}

    void doSomething(char c) {int i, time;for (i = 0; i < 3; i++) {

    // P operationif (sem_wait(&sem) == 0) {

    // generate random amount of time (< 30seconds)

    time = (int) ((double) rand() / RAND_MAX *30);

    printf("Thread %c enters and sleeps for %dseconds...\n", c, time);

    sleep(time);

    printf("Thread %c leaves the criticalsection\n", c);

    // V operation

    Page 5 of 7Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_semaphores.html

  • 8/13/2019 Group19 Semaphore

    50/68

    Run the program:

    -lpthread and -lrt are options passed into the compiler to use pthreads and

    POSIX semaphores.

    Output

    sem_post(&sem);}

    }}

    void *doSomething1() {

    // thread AdoSomething('A');

    return 0;}

    void *doSomething2() {// thread BdoSomething('B');

    return 0;}

    void *doSomething3() {// thread CdoSomething('C');

    return 0;}

    $ gcc -Wall -o sem sem.c -lpthread -lrt$ ./sem

    Thread A enters and sleeps for 25 seconds...Thread B enters and sleeps for 11 seconds... Thread B leaves the critical section Thread B enters and sleeps for 23 seconds...

    Thread A leaves the critical sectionThread A enters and sleeps for 23 seconds...

    Thread B leaves the critical section Thread B enters and sleeps for 27 seconds...

    Page 6 of 7Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_semaphores.html

  • 8/13/2019 Group19 Semaphore

    51/68

    The indentation and use of colours are to make the output a bit easier to read.

    Two lines that have the same colour and indentation level indicate that they are

    the correspoding entry and exit to and from the critical section of one thread.

    With the use of a random amount of sleeping time inside the critical section, we

    can see the interleavings of the threads more clearly. We also notice that there

    are at most two threads in the critical section at the same time (i.e. at most two

    nested "enters..." with different colours). This is what we expect because the

    semaphore is initialized to 2.

    Through this example, we have shown how POSIX semaphores can be used. We

    also go through the output of the program and verify that the maximum number

    of threads that can be in the critical section at the same time is exactly the initial

    value of the semaphore.

    References 1. Semaphores

    2. Synchronizing Threads with POSIX Semaphores

    3. Linux man pages

    4. Semaphores, Message Queues and Shared Memory 5. IPC:Semaphores (Information on UNIX System V IPC Semaphores, another

    way to implement/use semaphores.)

    [ Previous: 2.3.1 POSIX Mutexes | Up: 2.3 POSIX Library | Next: 2.4 Case Study

    on Prex Semaphore ]

    Thread A leaves the critical section Thread A enters and sleeps for 5 seconds... Thread A leaves the critical section Thread C enters and sleeps for 10 seconds...

    Thread B leaves the critical sectionThread C leaves the critical section

    Thread C enters and sleeps for 23 seconds... Thread C leaves the critical section Thread C enters and sleeps for 8 seconds... Thread C leaves the critical section

    Page 7 of 7Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/posix_semaphores.html

  • 8/13/2019 Group19 Semaphore

    52/68

    [ Previous: 2.3.2 POSIX Semaphores | Up: 2. Implementation | Next: 3.

    Advantages and Disadvantages ]

    2.4 Case Study on Prex SemaphoreIn this section, we study the implementation of semaphore in Prex , a portable

    real-time operating system for embedded systems. Prex provides fundamental

    features for synchronization with mutexes/semaphores, and at the same time,the source code is not too complicated to understand. In addition, the website

    provides a nice way to browse the source code .

    The data structure for semaphore:

    The magic number is used to check whether an object is a semaphore. This is

    true only if the magic number is equal to the constant SEM_MAGIC. event is a

    data structure used to sleep or wake up a process.

    There is a queue to keep track of the processes waiting on a semaphore. We will

    see later that the order the processes are waken up is not necessarily FIFO.

    struct semaphore {int magic; /* Magic number */task_t task; /* Owner task */

    struct event event; /* Event */u_int value; /* Current value */

    };

    struct event {struct queue sleepq; /* Queue for waiting thread */char *name; /* Pointer to event name string */

    };

    Page 1 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    53/68

    The following operations on semaphore can be found in root/sync/sem.c .

    Creating a Semaphore

    __syscall int sem_init(sem_t *sem, u_int value)

    {struct semaphore *s, *sem_org;int err = 0;

    ...

    /* Disable the thread switch to ensuresynchronization */

    sched_lock();

    /* Copy the pointer from user to kernel space */

    if (umem_copyin(sem, &sem_org, sizeof(sem_t))) {...}

    /* An application can call sem_init() to reset the* value of existing semaphore. So, we have to check* the semaphore is already allocated.*/

    if (sem_valid(sem_org)) {

    /* Semaphore already exists.

    * We modify the value only if:* (i) the thread is the owner of the semaphore* or it has the right to access another thread's

    semaphore.* (ii) no process is waiting on the semaphore*/

    if (sem_org->task != cur_task() &&!task_capable(CAP_SEMAPHORE))

    err = EPERM;else if (event_waiting(&sem_org->event))

    err = EBUSY;else

    s->value = value;} else {

    /* Create new semaphore.** First we allocate memory block for kernel*/

    if ((s = kmem_alloc(sizeof(struct

    Page 2 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    54/68

    In the above code, we copy the pointer from user to kernel space and check

    whether the pointer points to a valid semaphore. If the pointer is valid, we

    modify the value of the semaphore only if we have the right to access the

    semaphore and no process is waiting on the semaphore. If the pointer is invalid,

    we create a new semaphore in the kernel space, initialize and copy it to the user

    space.

    Destroying a Semaphore

    semaphore))) == NULL)err = ENOSPC;

    else {

    /* Initialize the semaphore */event_init(&s->event, "semaphore");

    s->task = cur_task();s->value = value;s->magic = SEM_MAGIC;

    /* Copy the pointer from kernel to user space*/

    if (umem_copyout(&s, sem, sizeof(sem_t))) {...

    }}

    }

    /* Unlock the thread switch */sched_unlock();

    return err;}

    __syscall int sem_destroy(sem_t *sem){

    sem_t s;int err;

    sched_lock();

    /* Copy the semaphore from user to kernel space* and check whether we have the right to access the

    semaphore

    Page 3 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    55/68

    If we have the right to access the semaphore and no process is waiting on the

    semaphore, we can destroy it. This is done by copying the semaphore to kernel

    space, setting the magic number to zero and finally free the memory block in

    kernel space associated with the semaphore.

    Waiting on a Semaphore

    */if ((err = sem_copyin(sem, &s))) {

    ...}

    /* If there is a process waiting on the semaphore,

    * the method fails with error*/if (event_waiting(&s->event)) {

    sched_unlock();return EBUSY;

    }

    /* Otherwise we destroy the semaphore */s->magic = 0;kmem_free(s);

    sched_unlock();

    return err;}

    __syscall int sem_wait(sem_t *sem, u_long timeout){

    sem_t s;int err;

    sched_lock();

    /* Copy the semaphore from user to kernel space* and check whether we have the right to access the

    semaphore*/

    if ((err = sem_copyin(sem, &s))) {...}

    Page 4 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    56/68

    while (s->value event, timeout);...

    /* Unlock and the lock the thread switch and

    * process all all pending woken threads*/sched_unlock();

    /* Lock the thread switch */sched_lock();

    }

    /* Finally the value of the semaphore is greater than0

    * and we can decrement it*/

    s->value--;

    sched_unlock();

    return 0;}

    int sched_tsleep(event_t event, u_long timeout){

    thread_t th;int stat;

    ...

    /* Disable interrupts (temporarily) */interrupt_save(&stat);interrupt_disable();

    /* Put the current thread to the sleeping queue ofthe semaphore */

    th = cur_thread;th->sleep_event = event;th->state |= TH_SLEEP;enqueue(&event->sleepq, &th->link);

    /* If timeout > 0, set the timer so that the sleepwill be cancelled

    * after the time limit expires and the thread will be removed

    Page 5 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    57/68

    In summary, if a process waits on a semaphore and the value of the semaphore

    is less than or equal to zero, the thread goes to sleep and is put on the queue of

    the semaphore. The sleep requests are not interruptible, and thus, the interrupts

    are disabled temporarily while the thread is being put to sleep. When the value

    of the semaphore is finally greater than one, we can decrement the value and let

    the thread enter the critical section.

    This is similar to sem_wait except that if the value of the semaphore is not

    greater than zero, it returns an error and the calling thread does not go to sleep.

    Incrementing a Semaphore

    * from the sleeping queue. This is similar tosem_timedwait of POSIX library

    */if (timeout)

    timer_timeout(&th->timeout, sleep_timeout, th,timeout);

    /* Process all pending woken threads to prepare for* the following thread switch call*/

    wakeq_flush();

    sched_switch(); /* Sleep here. Zzzz.. */

    /* Restore interrupts */interrupt_restore(stat);

    return th->sleep_result;}

    __syscall int sem_trywait(sem_t *sem)

    __syscall int sem_post(sem_t *sem){

    sem_t s;int err;

    sched_lock();

    Page 6 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    58/68

    /* Copy the semaphore from user to kernel space* and check whether we have the right to access the

    semaphore*/

    if ((err = sem_copyin(sem, &s))) {...

    }

    ...

    s->value++;if (s->value > 0)

    /* Please see the code of sched_wakeone() below*/

    sched_wakeone(&s->event);

    sched_unlock();

    return 0;}

    thread_t sched_wakeone(event_t event){

    queue_t head, q;thread_t top, th = NULL;

    ...

    /* Disable hardware interrupts */irq_lock();head = &event->sleepq;if (!queue_empty(head)) {

    q = queue_first(head);top = queue_entry(q, struct thread, link);

    /* Traverse the sleeping queue of the semaphoreand

    * select the highest priority thread

    */while (!queue_end(head, q)) {th = queue_entry(q, struct thread, link);if (th->prio < top->prio)

    top = th;q = queue_next(q);

    }

    /* Remove the selected thread from the

    Page 7 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    59/68

    We increment the value of the semaphore. If it is greater than zero, the highest

    priority thread among the sleeping threads is waken up. It is interesting to note

    that although we always add a thread to the end of the sleeping queue, we do

    not dequeue the threads in FIFO order. Priority is used instead.

    Getting the Value of a Semaphore

    sleeping queue and* wake it up*/

    queue_remove(&top->link);enqueue(&wakeq, &top->link);timer_stop(&top->timeout);

    }

    /* Restore hardward interrupts */irq_unlock();

    return th;}

    __syscall int sem_getvalue(sem_t *sem, u_int *value){

    sem_t s;int err;

    sched_lock();

    /* Copy the semaphore from user to kernel space* and check whether we have the right to access the

    semaphore*/

    if ((err = sem_copyin(sem, &s))) {...

    }

    /* Copy the value of the semaphore from kernel touser space */

    if (umem_copyout(&s->value, value, sizeof(int)))err = EFAULT;

    sched_unlock();

    return err;

    Page 8 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    60/68

    We copy the semaphore from user to kernel space, get the value of the

    semaphore and copy the value back to user space to return.

    Summary

    We have gone through the code related to semaphore in the Prex operating

    system. Through the case study, we have a better understanding of the

    implementation of sempahore in an operating system, e.g. the distinction

    between user and kernel space, the need to disable interrupts temporarily, the

    use of sleeping queue and the choice to pick the highest priority thread to wake

    up. Interested readers can also have a look at the implementation of mutex and

    condition variable in this operating system.

    References 1. Browse Prex Source

    [ Previous: 2.3.2 POSIX Semaphores | Up: 2. Implementation | Next: 3.

    Advantages and Disadvantages ]

    }

    Page 9 of 9Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/case_study.html

  • 8/13/2019 Group19 Semaphore

    61/68

    [ Previous: 2.4 Case Study on Prex Semaphore | Up: Site Map | Next: 4.

    Alternatives ]

    3. Advantages and DisadvantagesAdvantages

    In semaphores there is no spinning, hence no waste of resources due to no

    busy waiting. That is because threads intending to access the critical section

    are queued. And could access the priority section when the are de-queued,

    which is done by the semaphore implementation itself, hence, unnecessary CPU

    time is not spent on checking if a condition is satisfied to allow the thread to

    access the critical section.

    Semaphores permit more than one thread to access the critical section, in

    contrast to alternative solution of synchronization like monitors, which followthe mutual exclusion principle strictly. Hence, semaphores allow flexible

    resource management.

    Finally, semaphores are machine independent, as they are implemented in the

    machine independent code of the microkernel services.

    Disadvantages

    Problem 1: Programming using Semaphores makes life harder as utmost care

    must be taken to ensure Ps and Vs are inserted correspondingly and in the

    correct order so that mutual exclusion and deadlocks are prevented. In addition,

    it is difficult to produce a structured layout for a program as the P s and Vs are

    scattered all over the place. So the modularity is lost. Semaphores are quite

    Page 1 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/advantages_disadvantages.html

  • 8/13/2019 Group19 Semaphore

    62/68

    impractical when it comes to large scale use.

    Problem 2: Semaphores involve a queue in its implementation. For a FIFO

    queue, there is a high probability for a priority inversion to take place wherein a

    high priority process which came a bit later might just have to wait when a low

    priority one is in the critical section. For example, consider a case when a new

    smoker joins and is desperate to smoke. What if the agent who handles the

    distribution of the ingredients follows a FIFO queue (wherein the desperate

    smoker is last according to FIFO) and chooses the ingredients apt for another

    smoker who would rather wait some more time for a next puff?

    References 1. Generic semaphore for concurrent access by multiple operating systems

    [ Previous: 2.4 Case Study on Prex Semaphore | Up: Site Map | Next: 4.

    Alternatives ]

    Page 2 of 2Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/advantages_disadvantages.html

  • 8/13/2019 Group19 Semaphore

    63/68

    [ Previous: 3. Advantages and Disadvantages | Up: Site Map | Next: 5. Conclusion ]

    4. AlternativesMonitors

    Well first and foremost its a language based mechanism, where in semaphores are low-

    level synchronization primitives. Monitors were also conceived to address the short

    comings of semaphores, in chief, the scattered nature of semaphores and the low level

    implementation, i.e. the convenience of forgetting P or a V, and to address the formerreason in a semaphore based implementation, if you want to make changes, it is absolutely

    compulsory to find all places in the code, and amend accordingly. Which might take a very

    long time, and could be error prone for obvious reasons.

    While semaphores is a special type of counter, monitors are a shared object. A monitor

    might have many entry points (condition variable), however, only one process can used to

    enter the monitor at any time. Hence, it implements mutual exclusion in contrast to

    semaphores (if init n > 1). A monitor consists of:

    Procedures that allow interaction with shared resources.

    A mutex lock, i.e. to allow only one process to utilize it

    The resources variables

    Invariant to avoid race conditions

    Suppose a procedure ought to be implemented if a certain condition is met, i.e a process

    can suspend itself and release the monitor, this is achieved with condition variable. Another

    process wanting to access that function/procedure would be queued for that particularprocedure.

    Continuing on with our favourite Hollywood actress Angelina Jolie, we would show how, her

    bank account could be implemented.

    monitor Jolieaccount {int balance := 0

    Page 1 of 5Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/alternatives.html

  • 8/13/2019 Group19 Semaphore

    64/68

    Notice that in the functions, P and V arent explicitly stated, this is because the compiler

    inserts it in.

    In the code above the invariant balance, specifies that the balance, reflect past transactions.

    Since the monitor has a lock associated only Jolie or Pitt could access the account in agiven time. So no worries to their millions.

    Suppose Jolie decided for every 1000$ she deposited, she wanted a $100 to be given to a

    charity, all that has to be done is to come and insert the relevant code in the function

    deposit. However, in the semaphore based implementation, each and every place where the

    critical section is, we would have to add it. So as you can see it would be very cumbersome.

    Lets look at the problem with the implementation of condition variables.

    function withdraw(int amount) {if amount < 0 then error "Amount may not be negative"else if balance < amount then error "Insufficient funds"else balance := balance - amount

    }

    function deposit(int amount) {if amount < 0 then error "Amount may not be negative"else balance := balance + amount

    }}

    class Account extends Object { private double balance = 0; private CondVar OKtoWithdraw = new CondVar;

    public synchronized void deposit(double amount) { balance = balance + amount;

    notifyAll(OKtoWithdraw);}

    public synchronized void withdraw(double amount) {while (amount > balance)

    wait(OKtoWithdraw); balance = balance - amount;}

    }

    wait(CondVar cond) { put the calling thread on the wait set of cond;

    release lock;Thread.currentThread.suspend();

    Page 2 of 5Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/alternatives.html

  • 8/13/2019 Group19 Semaphore

    65/68

    There is one condition variables declared here, OktoWithdraw. In this monitor, the deposit

    method/function/procedure after updating the balance, calls notifyAll(OktoWithdraw), in

    which, it would notify all threads in queue and they would resume activity. The rationale

    behind this is we may have some thread not able to withdraw the money because the

    amount is greater than the balance. After a deposit, we would want that thread to resume

    activity and check whether the balance now contains enough money for withdrawal.

    When withdrawing, the procedure checks if the amount requested for withdrawal is greaterthan the balance and then calls the wait(OKtoWithdraw). In the wait method, the calling

    thread is enqueued in the queue associated with the condition variable OktoWithdraw. The

    monitor lock is released and the calling thread suspends operation. The other threads which

    were waiting earlier for the monitor lock now try to acquire the lock again. If the thread

    requests more money than the balance, it is made to wait (again) and the lock is passed on

    to the next thread trying to access it. When the condition finally becomes true, i.e. the

    amount of withdrawal is less than the balance (maybe after a deposit), the line "balance =

    balance - amount;" is carried out to update the balance.

    Java Synchronization (Monitors)

    Java uses the synchronized keyword to block a statement or a chunk of code so that only

    one thread can access it at a time. The synchronized keyword acts like a lock and it

    blocks all other threads from entering into that section of code, when it is being used by a

    thread. This is the Java way of implementing monitors.

    In addition to placing the synchronized keyword before a chunk of code, it may also beused in conjunction with wait,notify or notifyAll statements, as these allow threads to

    wait when another thread wants to take over the synchronized code.

    Lets understand better with the following code:

    Hope you all remember the scenario where Angelina Jolie and Brad Pitt tried accessing

    Jolies account at the same time and was left with $0! Well so the banks nowadays

    acquire lock;}

    notifyAll(CondVar cond) {forall t in wait set of condt.resume()

    }

    Page 3 of 5Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/alternatives.html

  • 8/13/2019 Group19 Semaphore

    66/68

    prevented that from happening by using a similar code like:

    The situation now becomes as we would prefer:

    /*** Make a deposit to this account* @param depositAmount amount to deposit in pennies*/

    public synchronized void deposit( long depositAmount ) throwsBankingException{

    if ( depositAmount < 0 ){

    throw new BankingException( "Negative deposits should behandled

    as corrections or withdrawals" );}this.balance += depositAmount;

    }

    /*** Make a withdrawal from this account* @param withDrawAmount amount to withdraw in pennies*/

    public synchronized void withdraw( long withdrawAmount ) throwsBankingException{

    if ( withdrawAmount < 0 ){

    throw new BankingException( "Negative withrawals should be handled as

    corrections or deposits" );

    }if ( balance < withdrawAmount ){

    throw new BankingException( "Insufficient funds" );}this.balance -= withDrawAmount;

    }

    Angelina Jolie Brad Pitt

    Load currentBalance=1 million

    Deposit newAmount=1 million

    (new balance 2 million)

    Update currentBalance=2 million

    Load currentBalance=2 million

    Page 4 of 5Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/alternatives.html

  • 8/13/2019 Group19 Semaphore

    67/68

    References 1. Multithreaded Programming with ThreadMentor: A Tutorial

    2. Semaphores & Monitors

    3. Monitor (Wikipedia)

    4. Semaphore vs Monitor

    5. Empirical Evaluation of a UML Sequence Diagram with Adornments to Support

    Understanding of Thread Interactions

    [ Previous: 3. Advantages and Disadvantages | Up: Site Map | Next: 5. Conclusion ]

    Withdraw newAmount=1 million

    (new balance 1 million)

    Update currentBalance=1 million

    Page 5 of 5Concurrency / Semaphore

    11/11/2007http://www.comp.nus.edu.sg/~phanquyt/cs2106/alternatives.html

  • 8/13/2019 Group19 Semaphore

    68/68

    [ Previous: 4. Alternatives | Up: Site Map ]

    5. ConclusionNow our journey with semaphores, unfortunately comes to an end. We looked at

    how semaphores are implemented in operating systems, how they are used in

    various situations and, in addition, other solutions such as monitors and

    condition variables to address the concurrency issue. The machine independentimplementation of semaphore and the POSIX library makes it a versatile tool for

    many platforms. On that note, we hope that you enjoyed this, as we did,

    exploring this crazy world of synchronization and concurrency. But please take

    note, this is just the tip of the iceberg, so be advent