Академический Документы
Профессиональный Документы
Культура Документы
Semaphores
When two or more processes or threads share some common
data, the final result of the shared data may depend on which process
executes first and precisely when. This is commonly referred as the
race condition problem. For example, two processes both increment
a shared counter. At the assembly language level, each process would
have code for counter increment like the following:
LOAD R1, M(counter);
// load the counter value to register R1
INC R1;
// increment the register R1
STORE R1, M(counter); // store the result back to counter
Assume the current value of the counter is 8. Then after both
processes complete their counter increment operations, we expect the
counter has value 10, no matter which process is executed first. But
when the two processes are executed concurrently the resultant value
of the counter may be 9, instead of correct value 10. Here is how it
may happen. Lets say the first process (P1) executes the LOAD
instruction and so R1 is equal to 8, then P1 proceeds to increment R1
to 9. Before P1 executes the STORE instruction to store the result
back to the counter, it is preempted by the other process (P2)
(because P1s time quantum is used up, for example). P2 executes its
LOAD instruction, since the modified value by P1 has not been stored
back to the counter yet, so R1 is 8. (Note: P1 and P2 have their own
contexts, when P2 starts its execution it has its own R1 through
context switch.) P2 proceeds to increment R1 by 1 and stores its
value, which is 9, to the counter. Later when P1 gets the CPU it
executes the STORE instruction which stores its R1 value, which is 9,
to the counter. Thus, the counter has incorrect value 9, instead of
correct value 10.
In this section we will introduce a process synchronization
mechanism called semaphores that may be used to solve the above-
9/19/2015 -- 3:47 PM
1/11
yes
value =
value -1
value >= 1
no
nothing
9/19/2015 -- 3:47 PM
2/11
yes
value >= 1
no
value =
value -1
Go to sleep
9/19/2015 -- 3:47 PM
3/11
yes
process
waiting?
no
Wakeup a
waiting
value =
value +1
C
Figure 3 Implementation of the V operation.
Description
Initialize a semaphore.
9/19/2015 -- 3:47 PM
4/11
blocking).
Post a semaphore.
Get the semaphore value.
Destroy a semaphore.
pshared is used for multiple processes to share the same semaphore. Since BrickOS does not support
processes, so this option is not applicable and is ignored.
9/19/2015 -- 3:47 PM
5/11
T2
S1
T3
S2
S3
S4
T2
.
T3
S1
S2
sem_post(sem1); sem_wait(sem1); sem_post(sem2);
sem_wait(sem2);
S3
sem_post(sem3);
sem_wait(sem3);
S4
6/11
9/19/2015 -- 3:47 PM
7/11
9/19/2015 -- 3:47 PM
8/11
contains either all 3s, by the first thread, or all 5s by the second
thread.
// filename: critical-sec.C
#include <config.h>
#include <conio.h>
#include <unistd.h>
#include <stdlib.h>
#include <dlcd.h>
#include <sys/tm.h>
#include "Semaphore.H"
int thread1(int argc, char** argv);
int thread2(int argc, char** argv);
class Shared {
private:
int shared[10];
public:
Shared(int x) {
for (int i=0; i<10; i++) shared[i] = x;
}
void set(int idx, int y) {
shared[idx] = y;
}
void print() {
for (int i=0; i<10; i++) {
lcd_int(shared[i]);
sleep(2);
lcd_clear();
sleep(1);
}
}
};
Shared shared(10);
Semaphore *mutex;
int value1 = 3;
int value2 = 5;
int main(int argc, char **argv)
{
tid_t pid1, pid2;
mutex = new Semaphore(1);
pid1 = execi(&thread1, 0, 0, 15, DEFAULT_STACK_SIZE);
lcd_int(pid1);
pid2 = execi(&thread2, 0, 0, 15, DEFAULT_STACK_SIZE);
lcd_int(pid1);
sleep(1);
cputs("before");
sleep(5);
shared.print();
cputs("after");
}
int thread1(int val, char** ptr) {
lcd_int(mutex->getValue());
mutex->wait();
lcd_int(mutex->getValue());
9/19/2015 -- 3:47 PM
9/11
9/19/2015 -- 3:47 PM
10/11
waiting threads, if any. Because the down() and up() operations are
synchronized methods, so the Java Virtual Machine guarantees their
mutual exclusion.
class Semaphore {
private int value;
};
Semaphore(int value) {
if (value < 0) throws
new IllegalArgumentException(value + <0);
this.value = value;
}
public synchronized down() throws InterruptedException {
while (value < 1) wait();
value = value 1;
}
public synchronized void up() {
value = value + 1;
notifyAll();
}
References
9/19/2015 -- 3:47 PM
11/11