본문 바로가기

23년 1학기 학교공부/운영체제및실습

[OS] Critical-Section Problem : Hardware Solution

목차

    728x90
    반응형
    SMALL

    critical section problem에서 하드웨어 지원을 받는 해결방법

    interrupt가 비활성화된 상태로 실행되는 특수한 instruction을 사용하는 방법이다.

    즉 automic operation을 이용하는 방법.

     

    지난 포스팅에서 설명했던 automic operation처럼 critical section을 automic operation으로 만들자는 것이 아니라, automic operation으로 만들어진 특수한 함수를 이용하여 entry section을 만들자는 것이다.

    운영 체제 안에 개발자들이 미리 작성해놓은 특별한 함수가 있는데, 이는 automic으로 실행되며 아주 짧은 시간에 실행되기 때문에 그 사이에 interrupt를 비활성화시켜도 컴퓨터 운영에 큰 문제가 없다.

    즉 위험성이 줄어들어 일반 사용자들이 안심하고 쓸 수 있다.

     

    대표적인 특별한 함수는 다음과 같은 testset instruction이 있다.

     

    📁 Testset instruction

    운영체제 개발자들이 운영체제 안에 구현해놓은 함수.

    이 함수가 실행되는 동안에는 automic하게 실행된다.

    위 코드가 실행시간이 오래 걸리지 않을까 우려할 수 있지만, 조건을 체크하고 조건에 맞게 실행하는 instruction은 간단한 편이며, 코드 수행 시 조건문은 전문 실행이 아니라 조건에 맞는 코드만 실행될거기 때문에 실제로 실행될 instruction이 많지 않다.

     

    먼저 argument로 넘어온 값이 0인가 확인 후 0이면 1로 바꾼다. 이를 test 후 set한다고 표현한다.

    만약 set했다면 true, set하지 않았다면 false를 리턴한다.

     

    📝 사용 예시

     

    위 코드는 p1부터 pn까지 프로세스를 만들어 동시에 실행하라는 뜻의 instruction이다.

    먼저 p1이 스케줄링되었다고 가정하자. 그러면 P() 함수를 수행한다.

    entry section의 testset while문을 수행할때, 현재 bold값은 초기값인 0이므로 1로 바뀌고 true가 리턴되는데 not 연산자가 있으므로 조건문은 false가 된다.

    이후 critical seciton을 실행하고, exit section에서 bolt값을 다시 0으로 만든다.

     

    만약 critical section을 수행중에 타임슬라이스가 끝나서 cpu가 p2에게 주어졌다고 해보자. p2도 위와 같은 방법으로 코드를 수행할것이다.

    그런데 그 전에 p1에서 bolt를 1로 설정해두었으므로, while문의 조건문은 true가 되어 critical section에 접근하지 못하고 busy waiting을 하게 된다.

    이후 타임슬라이스가 끝나고 p1이 아닌 어떠한 다른 프로세스에게 cpu가 주어진다고 하더라도 똑같이 busy waiting을 하게 된다. 스케줄링으로 p1이 cpu를 다시 받고 이어서 exit section까지 진행하지 않는 이상 다른 프로세스는 critical section에 접근할 수 없다.

     

    즉 하드웨어적 solution에서는 critical section 자체를 automic하게 만드는 것이 아니라, 특별한 automic 함수인 testset 함수를 사용하는 것이다.

    이 방법은 software적인 방법에 비해 굉장히 효율적이다.

     

    📁 Testset의 단점

    1. busy waiting을 사용한다.

    만약 A 프로세스가 critical section을 실행하다 말고 B 프로세스에게 cpu가 넘어왔을때, B는 본인이 cpu를 가지고 있음에도 불구하고 cpu 타임을 소모하면서 entry section의 while문을 반복실행할수밖에 없다. 이는 cpu를 효율적으로 사용하지 못하는 셈이 되므로 좋은 방법이 아니다.

    2. bounded waiting이 보장되지 않는다.

    대부분 bounded waiting이 보장되지만, 이론적으로 testset 방법에서는 보장되지 않을 수 있다.

    담장 바깥에서 busy waiting하며 기다리는 프로세스보다 다른 프로세스들이 먼저 스케줄링되어 먼저 온 프로세스가 오래 기다릴 수 있는 문제가 이론적으로는 생길 수 있고, testset은 이를 근본적으로 해결할 수 없다.

    단점이라고는 하지만, 웬만하면 일어나지 않는 일이기 때문에 무시해도 된다.

    3. Deadlock이 발생할 수 있다.

    Deadlock이란 서로 상대방이 지지하고 있는 리소스를 사용하려고 기다리는 상태를 말하며, 어떤 프로세스도 더 이상 진행하지 못하고 영원히 교착되는 상황을 말한다.

    예를 들어 p1과 p2 프로세스가 있다고 가정하자. 우선순위는 p1보다 p2가 높다. 일반적으로 스케줄링은 우선순위가 높은 프로세스에게 cpu를 우선한다. 만약 우선순위가 낮은 프로세스가 실행중인데 더 높은 프로세스가 생기면 cpu를 뺏는다.

    만약 p1이 critical section 안에 있다고 하자. 그런데 이때 우선순위가 높은 p2 프로세스가 생기면 p2가 p1의 cpu를 뺏어간다. 그러면 p1은 cpu를 뺏겼기 때문에 running에서 ready 상태가 되었고, p2가 running 상태가 된다.

    이 상태에서 p2가 critical section을 실행하려고 하는데, 이때 p1이 critical section을 실행하다 말았으므로 entry section에서 걸린다.

    p2는 cpu를 가지고 있지만 entry section에서 기다려야하고, critical section으로 들어가기 위해서는 p1이 나와야한다. 하지만 p1이 나오려면 cpu를 가져야 하는데 우선순위가 높은 p2가 있으므로 가질 수 없다.

    즉 두 프로세스가 서로 필요로 하는 자원을 가진 상태로 묶인 것이다.

     

    현재 운영체제에서는 위 deadlock 상황에 대한 보완방법을 마련했다.

    cpu를 뺏긴 프로세스에게도 오랜 시간 기다리면 다시 실행될 수 있는 자격을 줘서 cpu를 주도록 하는 방법이다.

    이렇게 되면 p1이 실행을 끝마치고 p2가 critical section에 들어갈 수 있으므로 교착상태가 풀릴 수 있다.

     

    ❓ 우선순위가 높은 프로세스가 critical section에 들어갈 수 있도록 모든 자원을 뺏도록 하면 되는것이 아닌가?

    물론 그렇다면 deadlock이 발생하지 않겠지만, 이와 같이 운영하게 되면 뺏기는 프로세스에게 너무 많은 피해가 가기 때문에 우선순위가 높은 프로세스는 cpu만 뺏어갈 수 있도록 해야한다.

     

    현대 운영체제에서는 deadlock에 대한 보완방법도 있기 때문에, 실질적으로 유일한 단점은 busy waiting이다.

    하지만 busy waiting도 꼭 나쁜것이 아니라 필요한 경우가 있기 때문에, testset이라는 이 하드웨어 지원을 받는 함수를 요즘도 사용한다.

    728x90
    반응형
    LIST