일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 파이썬 웹크롤링
- Next.js
- 파이썬 코딩테스트
- c++
- 네이버 부캠
- 씨쁠쁠
- 자바스크립트 객체
- 코딩테스트
- 파이썬
- 프로그래머스
- 자바 프로젝트
- beautifulsoup
- react
- PubSub 패턴
- React ssr
- Next/Image 캐싱
- Server Side Rendering
- 멘션 추천 기능
- 부스트캠프
- git checkout
- 네이버 부스트캠프
- React.js
- 웹크롤링
- 스택
- 브라우저 동작
- 자바스크립트
- 비디오 스트리밍
- 네이버 부스트캠프 멤버십
- 자바스크립트 컴파일
- Image 컴포넌트
- Today
- Total
코린이의 개발 일지
[운영체제] 프로세스 동기화 본문
프로세스 동기화란?
- 프로세스들 사이에 수행 시기를 맞추는 것
수행 시기를 맞춘다는 것은 크게 아래 두가지를 말한다
- 실행 순서 제어: 프로세스를 올바른 순서대로 실행하기
- 상호 배제: 동시에 접근해서는 안되는 자원에 하나의 프로세스만 접근하게 하기
1. 실행 순서 제어를 위한 동기화
- 동시에 실행되는 프로세스를 올바른 순서대로 실행하는 것
2. 상호 배제를 위한 동기화
- 상호 배제(mutual exclusion)는 공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘이다.
- 동시에 접근해서는 안되는 자원에 동시에 접근하지 못하게 하는 것.
- 두개 이상의 프로세스가 임계 구역에 동시에 접근하지 못하도록 관리하는 것.
프로세스뿐만 아니라 스레드도 동기화 대상이다.
정확히 말하면 실행의 흐름을 갖는 모든 것은 동기화의 대상이다.
공유 자원과 임계 구역
그렇다면 동시에 접근해서는 안되는 자원이란 뭘까?
예를 들어 총합 sum이라는 변수를 하나 두고 10으로 초기화 한다.
그리고 생산자 함수와 소비자 함수가 있다고 해보자
함수의 형태는 아래와 같이, 생산자는 sum을 1씩 더하고, 소비자는 sum을 1씩 뺀다고 했을 때,
생산자() {
sum++;
}
소비자() {
sum--;
}
생산자를 100000번, 소비자를 100000를 실행하면
sum은 그대로 10이어야 하지만, 총합이 전혀 다르게 나올 수 있다.
이는 생산자 프로세스와 소비자 프로세스가 제대로 동기화 되지 않았기 때문이다.
생산자와 소비자 모두 sum이라는 데이터를 동시에 사용하는데, 생산자가 소비자의 작업이 끝나기도 전에 총합을 수정하거나, 소비자가 생산자의 작업이 끝나기도 전에 총합을 수정했으면 제대로된 결과가 나오지 않는다.
생산자 함수를 low level 언어로 컴파일해서 실행한다고 했을 때 3단계로 나눌 수 있다.
- sum값 읽어오기
- sum에 1 더하기
- sum 값 저장하기
만약 sum = 10인 상태에서 생산자 한번, 소비자 한번 실행한다고 해보자.
그럼 결과 값은 그대로 10이 나와야한다.
하지만 만약 생산자 실행 단계에서 2번까지 수행하고 context switching이 발생해서 소비자 프로세스가 실행되었다면, 생산자가 1더한 값을 아직 저장하지 않았기 때문에, 소비자가 읽어오는 값은 그대로 10이된다. 소비자는 10에서 1을 빼고 다시 context switching이 일어나서 생산자 프로세스가 실행된다.
생산자는 아까 수행한 연산의 결과인 11을 저장하고, 프로세스가 종료되었으니 다시 context switching으로 소비자 프로세스가 실행된다.
소비자 프로세스는 수행한 연산의 결과인 9를 최종적으로 sum에 저장하게 되고
결국 sum은 우리가 의도했던 결과인 10이 아닌 9가 되게 된다.
공유 자원
이렇게 위의 예시 sum 변수처럼 여러 프로세스가 함께 사용하여, 동시에 실행하면 문제가 발생하는 자원을 공유 자원 (shared resource)라고 한다.
임계 구역
또한 공유 자원(동시에 실행하면 문제가 발생하는 자원)에 접근하는 코드 영역을 임계 구역(critical section)이라고 한다.
따라서 두개 이상의 프로세스가 임계 구역에 진입하고자 하면 둘 중 하나는 대기해야 한다.
임계 구역은 두 개 이상의 프로세스가 동시에 실행되면 안되는 영역이지만, 잘못된 실행으로 인해 여러 프로세스가 동시 다발적으로 임계 구역의 코드를 실행하여 문제가 발생하는 경우가 있다.
이를 레이스 컨디션(race condition)이라 한다.
위에서 다룬 예시 역시 레이스 컨디션의 사례라고 볼 수 있다.
운영체제는 이러한 임계 구역 문제를 아래 세 가지 원칙 하에 해결한다.
- 상호 배제(mutual exclusion): 한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 임계 구역에 들어올 수 없다.
- 진행(progress): 임계 구역에 어떤 프로세스도 진입하지 않았다면 임계 구역에 진입하고자 하는 프로세스는 들어갈 수 있어야 한다.
- 유한 대기(bounded waiting): 한 프로세스가 임계 구역에 진입하고 싶다면 그 프로세스는 언젠가는 임계 구역에 들어올 수 있어야 한다.(임계 구역에 들어오기 위해 무한정 대기해서는 안된다.)
동기화 기법
뮤텍스 락
- 뮤텍스 락 (Mutex lock: MUTual EXclusion lock)은 동시에 접근해서는 안 되는 자원에 동시에 접근하지 않도록 만드는 도구이다.
- 즉 상호 배제를 위한 동기화 도구이다.
형태
뮤텍스 락의 단순한 형태는 하나의 전역 변수와 두 개의 함수로 구현할 수 있다.
- 전역 변수 lock: 프로세스들이 공유하는 전역변수로, 자물쇠 역할을 함
- acquire 함수: 임계 구역을 잠그는 역할을 하는 함수.
- release 함수: 임계 구역의 잠금을 해제하는 역할
acquire 함수
- 프로세스가 임계 구역에 진입하기 전에 호출하는 함수
- 만약 임계 구역이 잠겨 있다면 lock이 false가 될 때까지 임계구역을 반복적으로 확인
- 임계 구역이 열려있다면 임계구역을 잠근다. (lock = true)
release 함수
- 현재 잠긴 임계 구역을 열어주는 함수
바쁜 대기
이와 같이 반복적으로 lock을 확인하며 대기하는 방식을 바쁜 대기(busy wait)라고 한다.
세마포
- 세마포(semaphore)는 뮤텍스락과 비슷하지만 좀 더 일반화된 방식의 동기화 도구이다.
- 공유자원이 여러개 있을 때 적용 가능한 동기화 도구이다.
- 세마포 종류에는 이진 세마포와 카운팅 세마포가 있으며 이진 세마포는 뮤텍스 락과 비슷하다.
- 공유 자원이 여러개 있을 때 적용 가능한 세마포는 카운팅 세마포이다.
형태
- 전역 변수 S: 사용 가능한 공유 자원의 개수를 나타내는 변수
- wait 함수: 임계 구역에 들어가도 좋은지, 기다려야 할지를 알려주는 함수
- signal 함수: 임계 구역 앞에서 기다리는 프로세스에 신호를 주는 함수
wait 함수
- S가 0이하라면 사용할 수 있는 자원이 있는지 반복적으로 확인
- S가 1이상이라면 S를 1감소 시키고 임계 구역 진입
signal 함수
- S 1증가
바쁜 대기
- 위의 방식도 마찬가지로 바쁜 대기를 하기 때문에, CPU를 낭비하는 문제가 있다.
실제 세마포는 이러한 문제를 해결할 더 좋은 방법을 사용한다.
wait 함수
- S가 0이하라면 해당 프로세스를 대기 상태로 만들고 그 프로세스의 PCB를 세마포를 위한 대기 큐에 집어 넣는다.
signal 함수
- 대기 중인 프로세스를 대기 큐에서 제거하고, 프로세스 상태를 준비 상태로 변경한 뒤, 준비 큐로 옮겨준다.
실행 순서 제어를 위한 동기화
- 위의 내용까지는 상호 배제를 위한 동기화 기법이었다면 세마포를 이용해 실행 순서 제어를 위한 동기화도 제어할 수 있다.
방법
- S를 0으로 두고, 먼저 실행할 프로세스 뒤에 signal 함수, 다음에 실행할 프로세스 앞에 wait 함수를 붙인다.
- 다음에 실행할 프로세스는 wait함수에 의해 대키큐에 들어가게 된다. 그리고 먼저 실행할 프로세스가 실행한뒤 signal 함수에 의해 S가 1이 되어야 비로소 다음에 실행할 프로세스가 대기큐에서 나와 실행될 수 있다.
모니터
매번 임계 구역 앞뒤로 일일이 wait, signal 함수를 명시하는 것은 번거로우며 자칫 잘못 사용하여 오류가 발생할 수 있다.
이에 최근에 등장한 동기화 도구가 모니터(monitor)이다.
모니터는 공유자원과 공유 자원에 접근하기 위한 인터페이스를 묶어 관리한다.
그리고 프로세스는 반드시 인터페이스를 통해서만 공유자원에 접근 가능하다.
모니터는 공유자원을 다루는 인터페이스에 접근하기 위한 큐를 만들고, 모니터 안에 항상 하나의 프로세스만 들어오도록 하여 상호 배제를 위한 동기화를 제공한다.
또한 모니터는 실행 순서 제어를 위해 사용하는 특별한 변수인 조건 변수(condition variable)을 사용한다.
조건 변수
- 특정 조건을 바탕으로 프로세스를 실행하고 일시 중단하기 위해 사용하는 변수
- 각각의 조건변수는 조건변수에 대한 큐가 존재하고, wait 명령어를 통해 큐에 들어가 대기상태로 있다가, signal 명령어를 통해 다시 실행을 재개할 수 있다.
'CS공부 > 운영체제 (OS)' 카테고리의 다른 글
[운영체제] 프로세스와 스레드 (0) | 2023.06.07 |
---|