group19 semaphore
Post on 04-Jun-2018
269 Views
Preview:
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
top related