본문 바로가기
운영체제

Critical Section Problem

by 세인트킴 2024. 3. 27.

Atomic instructions

원자와 같은 명령어. 한번 시작을 하면 끝을 내야하는 명령어. 실행 도중에는 멈추지 않는다. 

Spin lock에서 숫자를 확인하고, 설정하는 그 사이에 switch가 발생하는데, 원자 명령어는 이것을 하나의 명령어로 구현하면 switch가 발생하지 않는다. all or nothing이라는 이름으로도 불린다. 

Test-and Set instruction

bool test_and_set(bool *flag) {
    bool old = *flag;
    *flag = True;
    return old;
}

<Solution>
lock = false
repeat
	while test-and_set(lock) do no-op;
    	ciritical section;
    lock - false;
    	remainder section;
until false

test_and_set()함수에 lock변수의 주소값을 넘겨준다. *flag는 lock의 주소를 old에 담고, *flag는 True로 바꾸면 old = false, lock = true가 되서, while문이 실행되고 no-op가 되어서 test_and_set을 반복 호출한다. 그리고 lock = false가 되면 반복문을 빠져나와서 문제를 해결한다.

하지만 이 방법은 여전히 busy-waiting이 발생한다는 문제가 남아있다. 

Peterson's Solution

#define FALSE 0 
#define TRUE 1
#define N 2

int turn;
int interested[N];
void enter_region(int process) {
	int other = 1 – process;
	interested[process] = TRUE;
	turn = process;
	while (turn == process && interested[other] == TRUE);
}

void leave_region(int process) {
	interested[process] = FALSE;
}

Peterson's Solution으로 문제를 해결할 수 있다. 그러나 busy waiting이 발생하고, 구현을 하면 가끔 오류가 생긴다. 즉 완전한 프로그램은 아니기 때문. 첫번째는 compiler optimization이 오류를 일으킨다. 컴파일러는 번역 & 코드를 살짝 수정해주는 역할을 하기 때문. 그리고 CPU는 1개의 코어를 가지고 있어도 병렬 처리 기능이 오류를 일으킨다. 

해결책

sleep()
wakeup()

Producer-Consumer Problem

#define N 100
int count = 0;

void producer() {
    int item;
    
    while(TRUE) {
    	item = produce_item();
        if(count == N) sleep();
        insert_item(item);
        count += 1;
        if(count == 1) wakeup(consumer);
    }
}

void consumer() {
    int item;
    
    while(TRUE) {
    	if(count == 0) sleep();
        item = remove_item();
        count -= 1;
        if(count == N-1) wakeup(producer);
    }
}

busy waiting을 없애고자 제안한 해결법. 그러나 문제는 둘 다 sleep()을 수행해서 동작하지 않는다는 문제가 발생.

producer가 if를 통해 count == N을 확인하고, sleep()을 하기 전, CPU는 consumer가 되서, 수행 한 뒤, if문을 통해 count == 0 을 확인하고, sleep()을 하면, consumer도 sleep, producer도 sleep을 해서 둘 다 sleep가 된다. 

'운영체제' 카테고리의 다른 글

Threads and Process  (0) 2024.03.25
Fork & exec  (0) 2024.03.18