[CS]프로세스 동기화

·2025년 10월 22일
0

CS

목록 보기
18/19

💡프로세스 동기화란?

여러 프로세스가 공유 자원의 일관성을 유지하는 것

  • 간단하게는 프로세스 수행 시기를 맞추는 것을 의미하며,
  • 정확히는 프로세스 실행 순서를 제어하고 동시에 접근할 수 없는 자원에 하나의 프로세스만 접근하게 하는 것을 뜻한다.
  • 프로세스는 이를 통해 데이터 일관성을 유지할 수 있다.

프로세스들의 수행 시기를 맞추는 것은 크게 아래 두가지를 일컫는다

  • 실행 순서 제어 : 프로세스를 올바른 순서대로 실행하기
  • 상호 배제 : 동시에 접근해서는 안되는 자원에 하나의 프로세스만 접근하게 하기

✅실행 순서 제어를 위한 동기화

reader writer problem

Writer라는 프로세스와 Reader라는 프로세스가 동시에 실행중이라고 가정해보자.

  • Writer 프로세스 : Book.txt 파일에 값을 저장하는 프로세스
  • Reader 프로세스 : Book.txt 파일에 저장된 값을 읽어 들이는 프로세스

  • 이 두 프로세스는 아무 순서대로 실행되어서는 안되며, Writer프로세스의 실행이 끝나야 Reader프로세스의 실행이 가능하다.
  • 즉, Writer프로세스가 Book.txt에 값을 저장하기도 전에 Reader 프로세스가 Book.txt를 읽어 들이는 것은 올바른 실행 순서가 아니며, Reader 프로세스는 Book.txt안에 값이 존재한다는 특정 조건이 만족되어야만 실행을 이어나갈 수 있다.

✅상호 배제를 위한 동기화

bank account problem

가령 계좌에 10만원이 저죽되어 있다고 가정해보자.

  • 프로세스 A : 현재 저축된 금액에 2만원을 넣는 프로세스

  • 프로세스 B : 현재 저축된 금액에 5만원을 넣는 프로세스

  • 프로세스 A와 B가 동시에 실행되었다고 가정할 경우, 당연히 우리는 17만원이 계좌에 남을것을 기대한다. 하지만 동기화가 제대로 이루어지지않은 경우 전혀 다른 결과가 나올 수 있다.
  • 그 이유는 A와 B모두 잔액 이라는 데이터를 동시에 사용하는데, A가 끝나기도 전에 B가 잔액을 읽어버리고, 작업을 실행하였기 때문이다.
  • 이렇게 동시에 접근해서는 안되는 자원에 동시에 접근하지 못하게 하는 것이 상호 배제를 위한 동기화이다.

생산자와 소비자 문제

  • 생산자와 소비자는 총합이라는 데이터를 공유하고 있다.
  • 생산자 : 버퍼에 물건을 넣은 후 물건의 총합에 해당하는 변수를 1증가 시킴
  • 소비자 : 버퍼에 물건을 빼낸 후 물건의 총합에 해당하는 변수를 1감소 시킴

  • 총합을 10으로 가정하고, 위와 같은 상태에서 생산자를 100,000번, 소비자를 100,000번 동시에 실행하면 우리는 총합 변수가 계속 10일 것이라고 기대한다.
  • 하지만 막상 동시에 실행해보면 10이 아닌 다른수가 되거나 실행 중 오류가 난다.
  • 이는 생산자 프로세스와 소비자 프로세스가 제대로 동기화되지 않았기 때문에 발생한 문제로, 총합이라는 데이터를 동시에 사용하지만 생산자와 소비자가 서로 작업이 끝나기도 전에 총합을 수정했기 때문이다.

✅공유 자원과 임계 구역

1️⃣공유 자원(shared recource)

  • 여러 프로세스 혹은 스레드가 공유하는 자원

2️⃣임계 구역(race condition)

  • 공유 자원에 접근하는 코드 중 동시에 실행하면 문제가 발생하는 코드 영역

3️⃣경쟁 조건(critical area)

  • 여러 프로세스가 동시 다발적으로 임계 구역의 코드를 실행하여 문제가 발생하는 상황

✅임계 구역 문제 해결 조건

위와 같은 임계구역 문제는 아래 세가지 원칙 하에 해결한다.
즉, 상호 배제를 위한 동기화를 위해서는 아래 세가지 원칙이 반드시 지켜져야만 한다.

1️⃣상호 배제(mutual exclusion)

  • 한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 임계 구역에 들어올 수 없다.
  • 임계구역 내에는 한번의 하나의 프로세스만 있어야함.

2️⃣진행의 융통성(progress flexibility)

  • 임계구역에 어떤 프로세스도 진입하지 않았다면, 진입하고자 하는 프로세스는 들어갈 수 있어야 함.

3️⃣경쟁 조건(critical area)

유한 대기(bounded waiting)

  • 한 프로세스가 임계 구역에 진입하고 싶다면, 그 프로세스는 언젠가는 임계 구역에 들어올 수 있어야 함.
  • 임계 구역에 들어오기 위해 무한정 대기해서는 안됨.

💡동기화 기법

✅뮤텍스 락(Mutex lock)

락을 가진 단 한명만 접근 가능

  • 상호 배제를 위한 동기화 도구
  • 임계 구역에 진입하는 프로세스는 지금 임계 구역에 있음을 알리기 위해 뮤텍스 락을 이용해 임계 구역에 자물쇠를 걸어둠
  • 다른 프로세스는 임계 구역이 잠겨 있다면 기다리고, 잠겨있지 않다면 임계구역에 진입 가능
acquire();		// 자물쇠가 잠겨 있는지 확인, 잠겨 있지 않다면 잠그고 들어가기
// 임계구역		  // 임계구역에서의 작업 진행
release();		// 자물쇠 반환
while (lock == true) /* 만약 임계 구역이 잠겨 있다면 */
; /* 임계 구역이 잠겨 있는지를 반복적으로 확인 */
  • acquire() 에서는 임계 구역에 잠겨 있을 경우 프로세스가 반복적으로 lock을 확인한다.
    바쁜 대기(busy wait)발생(CPU 사이클 낭비)

✅세마포어(semaphore)

접근 가능 개수 제한

  • 공유 자원이 여러 개 있는 상황에서도 적용이 가능한 동기화 도구

  • Semaphore(n)
    - 사용 가능한 공유 자원의 개수를 나타내는 전역 변수

  • P(wait)

    • 임계구역에 들어가도 되는지, 기다려야 할지를 알려주는 함수
    • 잠금을 수행하는 코드
    • RS가 0보다 크면(사용 가능한 자원 있다는 뜻) 1만큼 감소시키고 임계구역에 진입함
    • 0보다 작으면(사용 가능한 자원 없다는 뜻) 0보다 커질 때까지 기다림(PCB 대기큐 삽입)
    • block()은 wake_up() 신호를 보낼 때까지 기다리는 함수
  • V(signal)

    • 임계구역에 들어가도 되는지, 기다려야 할지를 알려주는 함수
    • 잠금을 수행하는 코드
    • RS 값을 1 증가 시키고 세마포어에서 기다리는 프로세스에 임계구역에 진입해도 좋다는 wake_up() 신호 보냄

📌세마포어의 바쁜 대기 해결 방법

  • 사용할 수 있는 자원이 없을 경우 대기 상태로 만듦
    (해당 프로세스의 PCB를 대기 큐에 삽입)
  • 사용할 수 있는 자원이 생겼을 경우 대기 큐의 프로세스를 준비 상태로 만듦
    (해당 프로세스의 PCB를 대기 큐에서 꺼내 준비 큐에 삽입)

✅모니터(monitor)

  • 공유 자원을 내부적으로 숨기고 공유 자원에 접근하기 위한 인터페이스만 제공함으로써 자원을 보호하고 프로세스 간에 동기화하는 방법

1️⃣ 임계구역에 접근하고자 하는 프로세스는 직접 P()나 V()를 사용하지 않고 모니터에 작업 요청을 함
2️⃣ 모니터는 요청받은 작업을 모니터 큐에 저장한 후 순서대로 처리하고 그 결과만 해당 프로세스에 알려줌

profile
배우고 기록하며 성장하는 백엔드 개발자입니다!

0개의 댓글