04. 프로세스 동기화

권한·2025년 11월 12일

운영체제

목록 보기
4/7

동기화

synchronization. 작업 사이의 수행 시기를 맞추는 것
프로세스 동기화 : 프로세스들 사이의 수행 시기를 맞추는 것
❗ 스레드도 동기화 대상. 실행의 흐름을 갖는 모든 것은 동기화의 대상임

  1. 실행 순서 제어
    (동시에 실행되는) 프로세스를 올바른 순서대로 실행하기
  2. 상호 배제mutual exclusion
    동시에 접근해서는 안되는 자원에 하나의 프로세스만 접근하게 하기는 안되는 자원에 하나의 프로세스만 접근하게 하기

생산자와 소비자 문제

#include <iostream>
#include <queue>
#include <thread>
using namespace std;

void produce();
void consume();

//queue<int> q;
int sum = 0;

int main() {

    cout << "초기 합계: " << sum << endl;
    thread producer(produce);
    thread consumer(consume);

    producer.join();
    consumer.join();
    
    cout << "producer, consumer 스레드 실행 이후 합계: " << sum << endl;
    
    return 0;
}

void produce() { // 버퍼에 데이터 삽입
    for(int i = 0; i < 100000; i++) {
        // q.push(1);
        sum++;
    }
}
// 주석된 코드들을 해제하고 실행하면 레이스 컨디션이 발생하여 오류. 해제 하지 않아도 오류
void consume() { // 버퍼에 데이터 빼내기
    for(int i = 0; i < 100000; i++) {
        // q.pop();
        sum--;
    }
}

실행 결과

💡 레이스Race 컨디션
잘못된 실행으로 인해 두 개 이상의 프로세스나 스레드가 동일한 자원을 동시에 접근하여 수정하려 할 때, 접근 순서에 따라 결과가 달라지는 상황

공유 자원과 임계 구역

  • 공유 자원shared resourse
    공동의 자원. 전역변수, 파일, 입출력장치, 보조기억장치
  • 임계 구역critical section
    공유 자원 중 두 개 이상의 프로세스가 동시에 실행하면 문제가 발생하는 자원에 접근하는 코드 영역

임계 구역 문제 세가지 원칙

  • 상호 배제
    한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 임계 구역에 진입 불가
  • 진행progress
    임계 구역에 어떤 프로세스도 진입하지 않았다면 임계 구역에 진입하고자 하는 프로세스는 진입할 수 있어야 함
  • 유한 대기bounded waiting
    한 프로세스가 임계 구역에 진입하고 싶다면 그 프로세스는 언젠가 임계구역에 진입할 수 있어야 함(임계구역 진입을 위해 무한정 대기해서는 안됨)

동기화 기법

뮤텍스 락

Mutex lock; MUTual EXclusion Lock
동시에 접근해서는 안되는 자원에 않도록 만드는(상호배제) 도구. 임계구역에 자물쇠를 걺. 하나의 공유 자원에 접근하는 경우 상정

  • 자물쇠 : 프로세스들이 공유하는 전역 변수 lock
  • 임계구역 잠금 : acquire 함수
    임계구역이 잠겨있다면 lock이 false가 될 때까지 임계구역 반복적 확인
    열려있다면 lock을 true로 바꿈
  • 임계구역 잠금 해제 : release 함수
    임계구역에서 작업이 끝나고 호출하는 함수. 현재 lock을 false로 바꾸는 함수
acquire() {
	while (lock == true) //임계구역이 잠겨있는동안
		; //임계구역 잠겨있는지 반복적 확인. busy wait
	lock = true; //임계구역 안잠겨있으면 잠금
}
release() {
	lock = false; //임계구역 작업이 끝나면 잠금 해제
}    

💡 바쁜 대기busy wait : 반복적으로 계속해서 잠김 확인

세마포

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

  • 전역 함수 S : 임계구역에 진입할 수 있는 프로세스 개수(사용가능한 공유자원의 개수)
  • wait 함수(down, P) : 임계구역에 들어가도 좋은지 / 기다려야 할지 알려줌
  • signal 함수(up, V) : 임계구역 앞에서 '들어가도 좋다' 신호를 줌
wait() {
	S--; //임계구역에 진입할 수 있는 프로세스가 하나 이상이면 S를 1 감소, 임계구역 진입
	if (S < 0) { //사용가능한 자원이 없는 경우
		Add this process to Queue; //해당 프로세스 PCB를 대기 큐에 추가
		sleep(); //대기상태로 전환
	}
signal() { //프로세스가 임계구역 작업끝나고 호출
	S++;//임계구역 작업 마친 후 S를 1 증가
	if (S <= 0) { 
		remove a process p from Queue; //대기 큐에서 프로세스 PCB를 제거
		wakeup(p); //프로세스 p를 준비상태로 전환
	}
}

⇒ 세마포는 busy wait이 없음!!!

💡 세마포의 종류

  • 이진 세마포binary semaphore : S가 0과 1 두 종류의 값만 가짐
  • 카운팅 세마포counting semaphore : S가 0이상의 값 가짐

세마포를 이용한 동시에 실행되는 프로세스 실행 순서 제어

세마포의 변수를 S = 0으로 두고, 먼저 실행할 프로세스 뒤 signal(), 다음에 실행할 프로세스 앞 wait()

모니터

monitor. 공유자원과 공유자원에 접근가능한 인터페이스(통로)를 묶어서 관리.
자원에 접근하고자 하는 프로세스를 큐에 삽입하고, 큐에 삽입된 순서대로 하나씩 공유자원을 이용하도록 함.
❗ 모니터 안에는 하나의 프로세스만 존재 가능. 자원 하나당 모니터 하나
💡 여기서 인터페이스는 공유자원을 제어하기 위한 메소드
(이미지에서 3개 인것일뿐 더 있을 수 있다)

실행 순서 제어를 위한 동기화 제공
→ 조건 변수condition variable : 특정 조건 바탕으로 프로세스 실행/일시중단 하는 변수(모니터와는 별개의 개념임)
모니터로 진입한 프로세스가 x.wait() 로 변수 x에 대한 wait를 호출했다면 x.signal() 을 통해 대기상태 → 준비상태가 되어 다시 모니터 안으로 들어올 수 있다.


profile
티스토리로 옮김

0개의 댓글