[혼공컴운] 혼공단 11기 - 5주차 (12장)

shyn26·2024년 2월 14일
0

혼공학습단

목록 보기
14/20

12. 프로세스 동기화

12-1. 동기화란?

동기화의 의미

  • 프로세스 동기화 : ‘정보·통신 분야에서의 동기화란 작업들 사이의 수행 시기를 맞추는 것’ → 프로세스들 사이의 수행 시기를 맞추는 것
    • 실행 순서 제어: 프로세스를 올바른 순서대로 실행하기
    • 상호 배제: 동시에 접근해서는 안 되는 자원에 하나의 프로세스만 접근하게 하기

producer consumer 문제

<출처> [생산자와 소비자 문제](https://github.com/kangtegong/self-learning-cs/tree/main/producer_consumer)

이 곳에 첨부된 producer_consumer.cpp는 Chapter 12에서 언급한 대표적인 동기화 문제를 간단히 코드로 구현한 것입니다.

코드는 크게 produce 라는 함수를 10만번 실행하는 producer 스레드와

consume 이라는 함수를 10만번 실행하는 consumer 스레드로 이루어져 있습니다.

    std::thread producer(produce);
    std::thread consumer(consume);

그리고 producerconsumer가 실행하기 전 총 합계에 해당하는 sum을 출력하고,

실행한 이후 총 합계를 출력합니다.

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

    producer.join();
    consumer.join();

    std::cout << "producer, consumer 스레드 실행 이후 합계: " <<  sum << std::endl;

produce 는 큐에 임의의 값(1)을 총 합계를 1 증가시키는 것을 10만번 반복하는 코드이고,

void produce() {
    for(int i = 0; i < 100000; i++) {
        //q.push(1);
        sum++;
    }
}

consume 은 큐의 값을 하나 뺴낸 뒤 총 합계를 1 감소시키는 것을 10만번 반복하는 코드입니다.

void consume() {
    for(int i = 0; i < 100000; i++) {
        //q.pop();
        sum--;
    }
}

위 코드는 얼핏 보면 아무런 문제가 없어 보일지 모르나 실행하면 예상치 못한 결과를 초래합니다.

큐에 값을 넣고 빼는 코드 (q.push(1), q.pop())을 포함하여 실행하면 에러가 발생하고,

이를 주석 처리하고 실행한다고 해도 실행 후 합계는 0이 아닌 전혀 다른 값이 됩니다.

큐에 값을 넣고 빼는 코드를 포함하여 실행하면 에러가 발생하는 이유는,

producer와 consumer 사이에 레이스 컨디션이 발생하여

큐에 아무것도 값이 남아있지 않았음에도 불구하고 값을 빼내려 했기 때문입니다.


공유자원과 임계구역

  • 공유 자원(shared resource) : 문제의 예시에서 동시에 실행되는 프로세스들은 전역 변수 ‘잔액’, ‘총합’ 이라는 공동의 자원을 두고 작업

    • 공유 자원은 전역 변수가 될 수도 있고, 파일이 될 수도 있고, 입출력장치, 보조기억장치가 될 수도 있음
  • 임계 구역(critical section) : 동시에 실행하면 문제가 발생하는 자원에 접근하는 코드 영역

    • 레이스 컨디션(race condition) : 임계 구역은 두 개 이상의 프로세스가 동시에 실행되면 안 되는 영역인데, 잘못실행해서 여러 프로세스가 동시 다발적으로 임계 구역의 코드를 실행하여 문제가 발생하는 경우

      • 계좌 잔액 문제, 생산자와 소비자 문제가 대표적 레이스 컨디션 사례

12-2. 동기화 기법

뮤텍스 락

  • 예 : 손님 - 프로세스 / 탈의실 - 임계구역

    • 탈의실 안에 사람 존재 여부 확인 - 잠금장치가 잠겨있는지 확인 → 뮤텍스 락
  • 뮤텍스 락(Mutex lock; MUTual EXclusion lock) : 상호 배제를 위한 동기화 도구, 동시에 접근해서는 안 되는 자원에 동시에 접근하지 않도록 만드는 도구

    • 자물쇠 역할: 프로세스들이 공유하는 전역 변수 lock
    • 임계 구역을 잠그는 역할: acquire 함수
    • 임계 구역의 잠금을 해제하는 역할: release 함수
  • 바쁜 대기(busy wait) : 마치 탈의실 문이 잠겨 있는지 쉴 새 없이 반복하며 확인해 보는 것


세마포(semaphore)

  • 뮤텍스 락보다 조금 더 일반화된 방식의 동기화 도구

  • 탈의실(공유자원, 임계구역)이 여러 개 일 때 사용 가능

  • 철도 신호기에서 유래한 단어

    • 임계 구역에 진입할 수 있는 프로세스의 개수(사용 가능한 공유 자원의 개수)를 나타내는 전역 변수 S
    • 임계 구역에 들어가도 좋은지, 기다려야 할지를 알려주는 wait 함수
    • 임계 구역 앞에서 기다리는 프로세스에 ‘이제 가도 좋다’고 신호를 주는 signal 함수

모니터(monitor)

  • 세마포의 잘못사용될 경우를 보완하여 현대에 등장한 동기화 도구

  • 세마포보다 사용자가 사용하기 더 편리함

    <참고> [동기화](https://github.com/kangtegong/self-learning-cs/tree/main/synchronization)

[⭐혼공단 미션 인증!⭐]

p.363 - 1번 문제


[⭐혼공단 미션 인증!⭐]

Ch.12(12-1) 임계 구역, 상호 배제 개념을 정리하기

[임계구역(critical section)]

공유 자원 중에는 두 개 이상의 프로세스를 동시에 실행하면 문제가 발생하는 자원이 있는데, 이런 자원에 접근하는 코드 영역

  • 두 개 이상의 프로세스가 임계 구역에 진입하고자 하면 둘 중 하나는 대기
  • 먼저 진입한 프로세스의 작업이 마무리되면 그제서야 기다렸던 프로세스가 임계 구역에 진입
  • 레이스 컨디션(race condition)잘못된 실행으로 인해 여러 프로세스가 동시 다발적으로 임계 구역의 코드를 실행하여 문제가 발생하는 경우

[상호배제(mutual exclusion)]

한 프로세스가 임계 구역에서 작업 중이면 다른 프로세스가 임계 구역에 들어갈 수 없도록 제어하는 것

  • 공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘
profile
Without haste, but without rest - J.W. von Goethe

0개의 댓글