| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- JPQL
- 컨테이너
- kafka
- DI
- Spring Data JPA
- @Transactional
- JdbcTemplate
- JWT
- docker compose
- 쿠버네티스
- Routing Key
- 페이징
- securitycontextholderfilter
- CORS
- 서블릿 컨테이너
- docker
- 스프링 부트
- Dead Letter Queue
- DLQ
- Web
- @ComponentScan
- AWS
- dockerhub
- MSA
- mybatis
- 지연 로딩
- Spring
- JPA
- Spring Container
- redis
- Today
- Total
look-forest
Critical Section Problem: 프로세스 동기화가 필요한 상황 본문
Critical Section Problem: 프로세스 동기화가 필요한 상황
studyHub 2021. 6. 9. 14:25지금까지는 프로세스나 스레드를 동시에 사용하는 멀티프로세싱, 멀티스레딩에 대해서 알아보았다.
CPU 이용률을 높히고 반응성이 좋아졌지만, 문제점도 존재한다.
이번 시간에는 어떠한 문제가 있는지 알아보겠다.
[문제] data inconsistency
프로세스나 스레드가 concurrently(시분할) or parallel(멀티코어)하게 진행될 경우, 공유 데이터의 일관성이 깨질 수 있다.
예를 들어, 아래 코드의 경우를 보자.
conurrent하게 실행될 경우, instruction 진행 '도중에' interrupted 될 수 있는데, 그 경우 data integrity가 깨질 수 있다.
int counter = 0;
void *run1(void *param){
for (int i = 0; i < 10000; i++)
counter++;
pthread_exit(0);
}
void *run2(void *param){
for (int i = 0; i < 10000; i++)
counter--;
pthread_exit(0);
}
int main(){
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, run1, NULL);
pthread_create(&tid2, NULL, run2, NULL);
pthread_join(tid1, NULL); //tid1, tid2가 context switching하며 번갈아 실행된다
pthread_join(tid2, NULL);
printf("%d\n", counter); //counter==0이 아닐 수 있다..!
}
count++, count--는 1개의 명령어처럼 보이지만, 사실은 기계어로 3개의 명령어이다.

count++이나 count-- 실행 도중 문맥 교환이 일어날 경우, 다음과 같이 데이터 일관성이 깨질 수 있다.
1. count=5이고 count++을 실행하던 도중 3번째 명령어에서 interrupted가 걸렸다.
count에 resigter1의 값이 아직 반영되지 못하고 PCB에 context가 저장된다.
2. 다음 스레드에서 count--가 실행됐는데, 이때 count=5이다. count--가 완전히 실행되어 count=4가 되었다.
3. 다시 context switch가 일어났을 때, 이전에 진행하던 명령어가 마저 실행된다. counter=register1=6
Critical Section Problem
예를 들어 한 계좌에 대하여 두 사람이 동시에 withdraw(), deposit()을 호출하여 계좌 잔액의 일관성이 깨질 수 있다.
Race Condition
이처럼 여러 프로세스나 스레드가 공유 자원에 동시에 접근해 조작하는 상황을 Race condition이라고 한다.

Critical section
공유 자원에 접근하는 코드 영역. 동시 작업하면 안 된다.
while(true){
{entry-section} //진입 권한 획득
{critical-section}
{exit-section} //권한 반환
{remainder-section}
}
한 프로세스가 임계 구역에서 실행하고 있으면, 다른 프로세스들은 임계구역에서 실행해선 안된다.
※ 비선점형(nonpreemptive) 커널에서는 경쟁 상황이 발생하지 않으므로 임계영역 문제를 고려할 필요가 없다
Synchronization
이러한 상황으로부터 data integrity를 보장하기 위해선 한 시점에 하나의 프로세스만 공유 자원에 접근하게 해야 한다.
즉, 동기화를 해야한다.
Critical Section Problem 해결을 위한 3가지 조건
1. Mutual Exclusion (상호 배제)
한 프로세스가 임계 영역에서 작업 중이라면, 다른 프로세스는 임계 영역에 진입할 수 없다.
임계구역 내에는 한 번에 하나의 프로세스만 있어야 한다.
▷ deadlock과 starvation 발생 가능
2. Progress (avoid deadlock)
비어 있으면 언제든 사용할 수 있어야 한다.
어떤 프로세스도 임계 구역에서 작업하고 있지 않다면, 다음 프로세스가 진입할 수 있어야 한다.
3. Bounded Waiting (avoid starvation)
무한 대기하지 않아야 한다. 즉, 특정 프로세스가 임계구역에 진입하지 못하면 안 된다.
진입 횟수에 제한을 두어 다른 프로세스도 임계 구역에 들어갈 수 있도록 한다.
single-core 환경에서의 단순한 해결책
Single-core 시스템에서는 단순하게 인터럽트를 방지하는 것만으로 임계영역 문제를 해결할 수 있다.
공유 자원이 변경 중인 중간에 interrupt가 걸리지 않도록 막는다.
하지만 멀티프로세서 환경에선 유연하지 못하다.
융통성 없이 모든 코어에서 인터럽트 발생을 막는다면 진행이 너무 더디게 된다..
참고 자료 & 이미지 출처
운영체제 공룡책 강의 (주니온 님)
Operating System Concepts, 10th Ed (Silberschatz et al)
쉽게 배우는 운영체제 (조성호 님)
'Computer Science > Operating System' 카테고리의 다른 글
| 임계 구역 문제 솔루션: OS, Language supported SW solution (0) | 2021.06.09 |
|---|---|
| 임계 구역 문제 솔루션: SW solution, HW solution (0) | 2021.06.09 |
| CPU Scheduling (0) | 2021.06.08 |
| Thread (0) | 2021.06.07 |
| 프로세스 간 통신 : IPC (0) | 2021.06.06 |