ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4. 프로세스 병행 제어와 동기화
    Computer Science/Operating System 2022. 3. 13. 18:01
    728x90

     

    메모리 또는 디스크에서 데이터를 가져와 CPU에서 여러 프로세스들이 동시에 데이터를 처리해야 하는 경우. 즉, 하나의 공유 데이터를 여럿이 동시에 접근할 때 생기는 것"경쟁 상태(race condition)"라고 한다.

     

     

    이로인해 데이터 최종 연산 결과는 마지막에 그 데이터를 다룬 프로세스에 따라 달라져 의도치 않은 결과가 발생할 수 있다. 이러한 경쟁 상태를 막기 위해 병행 프로세스는 동기화되어야 한다.

     

    프로세스 동기화는 쉽게 말해 여러 개의 프로세스가 공유하고 있는 자원에 대해서 프로세스마다 순서를 정해 자원의 일관성을 유지해주는 것이다. 그렇다면 경쟁상태가 발생하는 여러 이유와 발생하지 않는 경우에 대해 알아보자.

     

     


    경쟁상태가 발생하는 경우

     

    - 커널 수행 중 인터럽트 발생 시


    커널모드 실행 중 인터럽트가 발생하여 인터럽트 처리루틴이 수행되면서 같은 커널 주소 공간 내 데이터를 접근하기 때문에 발생한다.

     


    해결 방안

    커널 모드 작업 중엔 인터럽트를 발생하지 않도록 disable 상태를 걸어놓고 작업이 끝난 후에 인터럽트를 수행하도록 하는 방식으로 해결할 수 있다.

     


    - 프로세스가 시스템 콜을 하여 커널 모드로 수행중이다가 문맥 교환이 일어날 시

     

    시스템 콜을 하는 동안 사용자 모드에서 커널 모드로 바뀌고 커널 주소 공간의 데이터를 접근하게 되는데 이 작업 도중 CPU 할당 시간이 끝나(타임아웃) 다른 프로세스가 CPU를 선점할 때 문맥교환이 일어나 이전에 저장됐던 데이터를 사용하게 되어 문제가 발생한다.

     


    해결 방안

    특정 프로세스가 커널 모드에서 작업을 수행중 일때는 CPU를 선점하지 않고 사용자 모드로 돌아갈 때 선점하게 만들어 해결할 수 있다.

     


    - 멀티 프로세서 시스템에서 공유 메모리 내부의 커널 데이터를 사용할 때


    여러 CPU가 서로 다른 프로세스의 작업을 수행하다 커널 내부 데이터에 동시 접근할 때 발생하는데 이 문제는 인터럽트 발생을 막아도 다른 CPU에서 데이터에 접근을 하기 때문에 인터럽트를 막는 방법으로는 해결할 수 없다. 

     


    해결 방안

    한번에 하나의 CPU만이 커널에 들어갈 수 있게 하는 방법이 있으나 많은 오버헤드가 발생 하므로 비효율적이다.

     

    따라서, 커널 내부에 있는 각 공유 데이터에 접근할 때마다 그 데이터에 대해 lock을 걸어 해당 작업이 끝날때까지 다른 CPU에서 그 데이터에 대한 접근을 막도록 하는 방법으로 해결할 수 있다.

     

     

    경쟁상태가 발생하지 않는 경우


    CPU의 개수와 상관없이 프로세스는 각자 자신의 프로세스 주소 공간을 사용하기에 보통 공유 데이터를 여러 군데에서 사용하는 경쟁 상태는 발생하지 않는다.

     

     


    프로세스 동기화 문제


    - 공유 데이터의 동시 접근은 데이터 불일치 문제 발생
    - 자원의 일관성 유지를 위해 협력 프로세스 간 실행 순서를 정해주는 메커니즘 필요


    n개의 프로세스가 공유 데이터를 동시에 사용하길 원하는 경우에서 공유 데이터를 접근하는 코드critical section이라 하며, 이때 하나의 프로세스가 critical section에 있을 때 다른 모든 프로세스는 이 영역에 들어갈 수 없어야 문제를 해결할 수 있다.

     

    동기화 문제 해결 방법의 충족 조건 


    - 상호 배제(mutual exclusion)

    임의의 프로세스 P가 critical section 부분을 수행 중이면 다른 모든 프로세스들은 해당 critical section에 들어가면 안되는 것을 말한다.

    - 진행(progress)
    cirtical section에 아무도 있지 않은 상태에서 critical section에 들어가고자 하는 프로세스가 있다면 critical section에 들어가게 해주어야 한다.

    - 유한대기(bounded waiting)
    프로세스가 critical section에 들어가려고 요청한 후 그 요청이 허용될 때까지 다른 프로세스들이 critical section에 들어가는 횟수에는 한계가 있어야 한다. 즉, 요청한 프로세스가 무한 대기하면 안된다.



    동기화 문제 해결 방법   


    - 직접 코드로 해결


    하드웨어적으로 Test & modify를 상황에 따라 수행할 수 있도록 지원해준다. Test_and_Set() 에서는 인자로 들어간 lock값을 읽어 들여 다른 프로세스가 critical section을 사용하고 있는지 확인하고 사용 여부에 따라 lock값을 바꿔준다.

    Synchronization variable
    	boolean lock = false;
    
    Process P
        do {
            while(Test_and_Set(lock));
            critical section
            lock = false;
            remainder section
        }while(1);

     

    처음에 lock은 false이므로 Test_and_Set(lock)을 호출하면 값을 읽어 critical section에 아무 프로세스가 들어가 있지 않는 것을 확인하고 lock을 true로 변경시킨 뒤에 작업을 수행한다. 작업이 끝난 후에는 다른 프로세스가 critical section을 사용할 수 있도록 unlock 상태를 만들어준다.



    - 동기화 문제를 해결해주는 수단을 이용해 해결


     1. 세마포어 (공유 자원에 대한 접근을 제한하는 방법)

     

    세마포어 정수 변수 mutex(lock/unlock의 용도)를 이용해 P(), V()를 호출해서 동기화문제를 해결하는데 mutex는 critical section을 사용할 수 있는지에 대한 자원의 개수를 의미한다.

     

     P()에서 mutex가 0보다 작거나 같다면 계속 대기하다 1이 되는 순간 자원을 써서 감소시킨다. V()에서는 critical section 사용이 끝난 상태로 mutex를 증가시킨다. 

    Synchronization variable
    semaphore mutex; 
    
    Process Pi
        do {
            P(mutex);
            critical section
            V(mutex);
            remainder section
        }while(1);

     

    아래는 P(), V() 함수가 수행되는 방식을 나타낸 코드이다.

     

    P(mutex):
        while(mutex<=0) do no-operation;
        mutex--;
    
    V(mutex):
        mutex++;


    특정 공유자원에 대해 두 개 이상의 프로세스나 스레드가 CPU에게 이용 권한을 얻고자 하는 동기화 상황의 바쁜 대기(spin lock) 방식은 비효율적이므로 block & wakeup(sleep lock) 방식으로 구현한다.

     

    이 경우 커널은 block()을 호출한 프로세스를 대기시키고 이 프로세스의 PCB를 대기 큐에 넣는다. 한 프로세스에서 자원 사용이 끝난 후 block된 프로세스를 wake-up시켜 PCB를 준비 큐로 옮긴다.


    세마포어의 문제점 


    아래와 같이 두 개의 공유 데이터를 프로세스 두 개가 쓰려하는데 각각 하나씩 동시에 차지하면서 다음 작업을 수행하기 위해 상대방의 것을 요구하게 된다.

     

     

    그러나, 해당 자원은 lock 상태이므로 요구하는 프로세스가 대기하게 되는데 이처럼 "둘 이상의 프로세스가 서로 상대방의 동작을 끝나기만을 기다려 아무 작업도 수행할 수 없는 무한히 대기하는 현상"인 교착상태(Deadlock)라는 문제가 발생한다.

     

     

    2. 모니터 

     

    동시 수행중인 프로세스 사이에서 추상 자료형 데이터에 대해 안전한 공유를 보장하기 위한 고수준 동기화 도구이다. 내부적으로 공유 데이터 접근에 대해 제어를 하여 동기화 해주는 코드가 있다.

     

    세마포어는 코딩하는 데 있어 복잡함이 있고 deadlock과 같은 현상을 보면 정확성 입증의 어려움이 있다. 또한, P(), V() 연산 순서가 바뀌게 되면 상호 배제 조건이 충족되지 않아 한번의 실수로 모든 시스템에 영향을 미치는 문제가 발생하는데 이를 해결해주는 도구가 모니터이다.

     

    세마포어의 문제


    모니터 내에서는 한번에 하나의 프로세스만이 작업을 수행할 수 있고, 프로그래머가 동기화 제약 조건을 명시적으로 코딩할 필요가 없다. 원자적인 lock/unlock과 같은 연산을 하지않는다.

     

     

    프로세스가 모니터 안에서 대기할 수 있도록 condition variable을 사용한다. 이 변수는 wait과 signal 연산에 의해 접근이 가능하다.  wait()을 호출한 프로세스는 작업중이었던 프로세스가 signal()을 호출할 때까지 대기하고, signal()이 호출되면 대기하고 있는 하나의 프로세스를 재개시킨다. 이때 대기중인 프로세스가 없다면 아무 일도 일어나지 않는다.

    728x90

    'Computer Science > Operating System' 카테고리의 다른 글

    6. 메모리 주소와 바인딩  (0) 2022.03.29
    5. 교착상태(Deadlock)  (0) 2022.03.21
    3. CPU 스케줄링  (0) 2022.03.07
    2. 프로세스 관리  (0) 2022.02.28
    1. 운영체제와 컴퓨터 시스템의 구조  (0) 2022.02.21

    댓글

Designed by Tistory.