Problem
do {
entry section
critical section
exit section
remainder section
} while(1);
가정
모든 프로세스의 수행 속도는 0보다 크다.
프로세스들 간의 상대적인 수행 속도는 가정하지 않는다.
do {
while(turn != 0);
critical section
turn = 1;
remainder section
} while(1);
do {
flag[i] = true;
while(flag[j]);
critical section
flag[i] = false;
remainder section
} while(1);
do {
flag [i] = true;
turn = j;
while (flag[j] && turn == j);
critical section
flag[i] = false;
remainder section
} while(1);
// 이 메서드가 원자적으로(atimic)하게 수행
boolean test_and_set(boolean *target) {
boolean rv = *target;
*target = true;
return rv;
}
//Synchronization variable
boolean lock = false;
//Process Pi
do{
while(test_and_set(lock));
critical section
lock = false;
remainder section
}
int compare-and_swap(int *value, int expected, int new_value) {
int temp = *value;
if(*value == expected)
*value = new_value;
return temp;
}
앞의 방식들을 추상화시킴
Semaphore S
// P는 자원을 획득
P (S) : while(S<=0) do no-op; //waiting
S--;
// V는 자원을 반납
V (S) : S++;
//Synchronization variable
semaphore mutex; // initially 1 (1개가 CS에 들어갈 수 있다.)
Process Pi
do {
P(mutex);
critical section
V(mutex);
remainder section
} while(1);
Busy-wait는 효율적이지 못함
typedef struct
{
int value; // semaphore
struct process *L // process wait queue
} semaphore;
block // 커널은 block을 호출한 프로세스를 suspend 시킴,이 프로세스의 PCB를 semaphore에 대한 wait queue에 넣음
wakeup(P) // block된 프로세스 P를 wakeup시킴, 이 프로세스의 PCB를 ready queue로 옮김
P (S) : S.value--;
if(S.value < 0)
{
block(); // add this process to S.L
}
V (S) : S.value++;
if(S.value >= 0)
{
wakeup(P); // remove a process P from S.L
}
import java.util.concurrent.atomic.AtomicBoolean;
public class Peterson {
private static int count = 0;
private static int turn = 0;
private static AtomicBoolean[] flag = new AtomicBoolean[]{new AtomicBoolean(), new AtomicBoolean()};
public static void main(String[] args) throws InterruptedException {
Thread producer = new Thread(new Producer());
Thread consumer = new Thread(new Consumer());
producer.start();
consumer.start();
producer.join();
consumer.join();
System.out.println(count);
}
private static class Producer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 30000; i++) {
flag[0].set(true);
turn = 1;
while (flag[1].get() && turn == 1) {
// waiting
};
count++;
System.out.println(Thread.currentThread().getName()+" producer in critical section 카운트 : "+count);
flag[0].set(false);
}
}
}
private static class Consumer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 30000; i++) {
flag[1].set(true);
turn = 0;
while (flag[0].get() && turn == 0) {
// waiting
};
// critical section
count--;
System.out.println(Thread.currentThread().getName()+" consumer in critical section 카운트 : "+count);
//exit section
flag[1].set(false);
//remainder section
}
}
}
}
import java.util.concurrent.atomic.AtomicBoolean;
public class TestAndSet {
private static AtomicBoolean lock = new AtomicBoolean(false);
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread producer = new Thread(new Producer());
Thread consumer = new Thread(new Consumer());
producer.start();
consumer.start();
producer.join();
consumer.join();
System.out.println(count);
}
public static class Producer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 30000; i++) {
while (lock.getAndSet(true)) {
//do noting..
System.out.println("producer waiting "+ lock);
}
//critical section
count++;
System.out.println("producer in critical section, count = " + count);
lock.set(false);
}
}
}
public static class Consumer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 30000; i++) {
while (lock.getAndSet(true)) {
//do noting..
System.out.println("consumer waiting "+ lock);
}
//critical section
count--;
System.out.println("consumer in critical section, count = " + count);
lock.set(false);
}
}
}
}
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class Cas {
private static AtomicBoolean lock = new AtomicBoolean(false);
private static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Thread producer = new Thread(new Producer());
Thread consumer = new Thread(new Consumer());
producer.start();
consumer.start();
producer.join();
consumer.join();
System.out.println(count);
}
public static class Producer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
while (lock.compareAndExchange(false, true) ) {
//do noting..
System.out.println("producer waiting "+ lock);
}
//critical section
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println("producer in critical section, count = " + count.incrementAndGet());
lock.set(false);
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}
public static class Consumer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
while (lock.compareAndExchange(false, true)) {
//do noting..
System.out.println("consumer waiting "+ lock);
}
//critical section
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println("consumer in critical section, count = " + count.decrementAndGet());
lock.set(false);
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}
}