티스토리 뷰

혼공컴운

[혼공컴운] 12장. 프로세스 동기화

게으른 the lazy 2024. 8. 2. 22:26

https://www.youtube.com/watch?v=eKKc0d7kzww

12. 프로세스 동기화

  • 줌으로 회의를 하다 보면 좀 불편할 때가 있다.
  • 두 명 이상이 동시에 말할 때다.
  • 그래서 손을 먼저 들고 말할 순서를 정하면 된다.
  • 하지만 사실 그것도 불편하다.
  • 프로세스도 동시에 실행되고 싶을 때가 있다.
  • 하지만 동시에 실행할 프로세스들이 같은 자원을 쓴다면 문제가 된다.
  • 줌 회의로 비유하자면, 공간과 시간(자원)을 같이 쓰고 싶은 두 사람이 있을 때의 문제이다.

12.1 동기화란

  • 아주 간단한 예시로, 같은 파일을 두 프로세스가 동시에 수정하는 경우 문제가 생길 수 있다.
  • 얼핏 생각하면 그게 왜 문제인지 와닿지 않을 수 있다.
  • 사람 기준이 아니라 컴퓨터의 기준으로 생각해야 한다.
  • 예를 들어, 파일의 값을 읽어서 1 증가시켜서 저장하려면 아래의 과정이 필요할 것이다. (틀릴 수 있음)
    • 프로세스가 OS를 통해 파일을 열어주기를 요청한다.
    • OS가 HDD 또는 SSD의 장치 컨트롤러에게 파일을 열어주기를 요청한다.
    • 장치 컨트롤러가 반응한다. 통로를 열어준다.
    • 프로세스가 적절한 명령을 만들어서 메모리에 올린다.
    • CPU가 메모리에서 명령을 가져간다. "파일의 값을 1 증가시켜주세요."라고 써있다.
    • 앞에서 만든 통로를 통해서 값을 가져온다. 이 값은 (아마도) 데이터 레지스터에 들어간다.
    • ALU가 값을 1 증가시킨다.
    • 이 값은 CPU 내의 제어 장치를 통해 다시 메모리에 기록된다.
    • 프로세스가 다시 OS에게 파일을 열어달라고 요청한다.
    • 파일과의 통로가 열리면 프로세스는 메모리에서 값을 가져와서 저장한다.
  • 이렇게 생각하면 왜 문제가 생기는지 바로 보인다.
  • 결국 모든 것은 어셈블리어나 기계어 등의 저급 언어로 변환되어 실행된다.
  • 저급 언어에서는 읽기 -> 증가시키기 -> 쓰기의 과정으로 실행된다.
  • 두 프로세스가 동시에 하나의 파일에 접근하면?
  • 하나가 작업을 완료하기 전에 다른 하나가 파일을 열어버리면?
  • 한 프로세스는 자신이 마지막으로 읽은 값을 기준으로 1을 증가시킨다.
  • 다른 프로세스가 같은 파일을 열어서 값을 가져갔는지 알 길이 없다!
    • 그래서 실제로는 하나의 파일은 하나의 프로세스만 접근 가능하게 만들기도 한다.

출처: https://www.scaler.com/topics/operating-system/process-synchronization-in-os/


  • 그래서 프로세스 동기화는 아래의 두 가지 원칙이 필요하다.
    • 실행 순서 제어: 프로세스를 옳은 순서대로 실행시키기
    • 상호 배제: 동시에 접근하면 위험한 자원에는 한번에 하나의 프로세스만 접근 허용하기
      • 동시에 접근하면 안되는 자원을 공유 자원(shared resource)이라고 부른다.
  • 동시에 실행하면 문제가 생기는 자원에 접근하는 코드 영역을 임계 구역(critical section)이라고 부른다.
  • 앞으로 이 용어는 중요하게 다룰 것이다.

출처: https://www.scaler.com/topics/operating-system/mutex-in-os/


12.1.1 개념 정리

  • 임계 구역(critical section)
    • 동시에 실행하면 문제가 생기는 공유 자원에 접근하는 코드 영역
  • 상호 배제(mutual exclusion)
    • 한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 임계 구역에 들어가지 못하게 하는 원칙

12.2 동기화 기법

  • 문제점을 알았으니, 해결할 방법이 필요하다.
  • 책에 나온 대로, 탈의실에 비유해서 설명해보겠다. 화장실은 이제 그만~
  • 탈의실 대기줄은 대기 큐로 생각할 수 있다.
  • 사람(프로세스)은 대기 줄(대기 큐)에서 자기 순서를 기다리고 있다.
  • 탈의실은 임계 구역이다.
  • 탈의실(임계 구역)에는 한 번에 한 사람만 들어갈 수 있다.
    • 심지어 부모도 못 들어가게 하더라. 그래서 부모 프로세스도 못 들어간다. (맞나?)

12.2.1 뮤텍스 락

  • 뮤텍스 락(Mutex Lock)의 개념은 간단하다.
  • 한 프로세스가 임계 구역에 들어가면, 자물쇠로 걸어잠근다.
  • 임계구역에서 빠져나오면, 자물쇠를 푼다.
  • 자물쇠는 전역 변수 lock으로 만들고 true/false를 가질 수 있다.
  • 프로세스가 임계 구역에 들어갈 때는 acquire() 함수를 실행한다.
acquire() {
  while (lock == true) // lock이 풀릴 때까지
    ;                  // 기다린다.
  lock = true;         // lock을 걸고 자신이 들어간다.
}
  • 프로세스가 수행을 마치고 나올 때에는 release() 함수를 실행한다.
release() {
  lock = false; // lock을 풀고 나온다.
}
  • 이제 각 프로세스는 아래와 같이 실행된다.
acquire();
// 자기 할 일 하기
release();
  • 다만 이 경우 lock이 풀릴 때까지 계속 확인하며 기다린다.
  • 이것을 바쁜 대기(busy wait)라고 부른다.

출처: https://www.scaler.com/topics/operating-system/mutex-in-os/


12.2.2 세마포

  • 세마포(semaphore)는 깃발 또는 빛을 이용한 신호 체계라는 뜻이다.

출처:

  • 동기화 얘기 하다가 갑자기 웬 깃발이냐고?
  • 프로세스에게 "들어가도 좋다!"라는 신호를 바로 깃발(flag)로 보내기 때문이다!
  • 실제로 많은 경우 true/false 또는 1/0만을 갖는 변수를 flag라고 쓰기도 한다.
  • CPU에 플래그 레지스터가 무엇이었는지 생각해봐도 좋겠다.

  • 프로세스 동기화에서 세마포란 여러 프로세스가 여러 자원에 접근해야 할 때 사용하는 기법이다.
  • 이때 깃발은 현재 비어 있는 자원의 개수를 말한다. 이 값은 전역 변수에 저장해둔다.
  • 이제 프로세스는 자기 순서가 오면 이 변수의 값을 확인한다.
  • 변수의 값이 0보다 커야 자원에 접근할 수 있다.

출처: https://os.mbed.com/docs/mbed-os/v5.15/apis/semaphore.html

  • 비어 있는 자원 개수를 전역 변수 S에 저장한다고 가정하자.
  • 자리가 나기를 기다리는 함수 wait()는 아래와 같다.
wait() {
  while (S <= 0) // 자리가 하나라도 날 때까지
    ;            // 기다린다
  S--;           // 자리가 났다! 들어가면서 S를 1 줄인다
}
  • 실행을 마치면 자리가 났다는 신호를 보낸다.
signal() {
  S--;           // 여기 자리 났어요!
}
  • 프로세스는 아래 과정으로 실행된다.
wait()
// 내 할 일 합니다.
signal()

  • 세마포는 한 가지 더 좋은 기능을 제공한다.
  • 뮤텍스 락에서는 프로세스가 자리가 날 때까지 계속 노크를 했다.
    • 화가 난다.
  • 세마포에서는 자리가 없으면 프로세스를 대기 상태로 만들고 PCB를 대기 큐에 넣어버린다.
  • 그리고 자리가 나면 signal()을 통해 프로세스를 깨운다.
  • 아래는 대기를 위한 함수이다.
wait() {
  S--;
  if ( S < 0 ) {
    // 대기 큐에 프로세스 삽입
    // 대기 상태로 전환
  }
}
  • 아래는 자원을 할당받는 함수이다.
signal() {
  S++;
  if ( S <= 0 ) {
    // 대기 큐에서 프로세스 꺼내기
    // 프로세스 깨움
  }
}

12.2.3 모니터

  • 모니터는 아예 공유 자원과 프로세스를 위한 인터페이스를 만들어버리는 기법이다.

출처: https://velog.io/@gabie0208/OS-Semaphores-Deadlock-Starvation-Monitors

  • 이제 프로세스는 반드시 이 인터페이스를 통해서만 공유 자원에 접근할 수 있다.
  • 공유 자원에 접근하려는 프로세스는 모니터의 큐에 집어넣는다.
  • 모니터는 자체적으로 상호 배제 원칙을 지키며 프로세스와 자원을 관리한다.
    • 조건 변수는 무슨 말인지 이해를 못해서 패스한다. 아 쿨하다.

12.2.4 확인 문제

  • 뮤텍스 락과 세마포에 대한 설명에 대해 틀린 것은?
    • 뮤텍스 락은 임계 구역을 잠근 뒤 임계 구역에 진입함으로써 상호 배제를 위한 동기화를 이룬다?
      • 맞다. 그걸 위해 자물쇠 변수를 이용한다.
    • 세마포는 공유 자원이 여러 개 있는 상황에서도 이용할 수 있다?
      • 그거 하려고 세마포 만든 거다.
    • 세마포를 이용해 프로세스 실행 순서 제어를 위한 동기화도 할 수 있다?
      • 가능하다. 프로세스 실행 앞뒤로 wait()signal()을 넣느냐 마느냐를 통해서 구현한다.
    • 세마포를 이용하면 반드시 바쁜 대기를 해야 한다?
      • 아니다. 대기 큐에 넣어놓고 signal()로 다시 불러올 수 있다.
댓글