반응형
더보기
목차
- 동기화의 고전 문제 3가지
- Bounded-Buffer Problem
- Readers and Writers Problem
- Solution 1
- Dining Philosophers Problem
- Solution 1
- Solution 2
동기화의 고전 문제
1. Bounded-Buffer Problem
- 문제 정의
- 프로세스 동기화에서 자주 등장하는 고전적인 문제로, 생산자-소비자 문제(Producer-Consumer Problem) 라고도 한다.
- N개의 아이템만 삽입할 수 있는 유한한 크기의 버퍼(Buffer)에서, 여러 생산자(Producer)와 소비자(Consumer) 가 동시에 접근하며 발생할 수 있는 Race Condition과 동기화 문제를 다룬다.
- 문제 동작 과정
- 생산자 (Producer)
- 데이터를 생성하여 버퍼에 저장한다.
- 작업 조건
- 버퍼에 꽉 차있지 않으면, 데이터를 추가할 수 있음
- 꽉 찼으면 대기해야 함
- 소비자 (Consumer)
- 버퍼에서 데이터를 가져와 처리한다.
- 작업 조건
- 버퍼에 데이터가 있으면 데이터를 가져갈 수 있음
- 비어 있으면 대기해야 함
- 문제 상황
- Race condition : 여러 프로세스가 동시에 버퍼에 접근하여 데이터를 읽거나 쓸 때, 데이터 일관성이 깨질 수 있음
- 동기화 문제
- 생산자가 데이터를 추가하려고 할 때, 버퍼가 가득 차 있으면 대기해야 함
- 소비자가 데이터를 가져가려고 할 때, 버퍼가 비어 있으면 대기해야 함
- 구현
- Buffer 의 구현
- boolean buffer[n] 1차원 배열로 선언
- buffer[0... n-1] = empty 로 초기화
- 생산자 Operation
- Buffer 배열 중, empty 인 index 를 찾아 full 로 바꿈
- buffer[m] = full
- 소비자 Opeartion
- buffer 배열 중, full 인 index 를 찾아 empty 로 바꿈
- buffer[m] = empty
- 문제 해결
- 생산자가 데이터를 추가하는 중에 소비자가 데이터를 가져가거나, 동시에 같은 슬롯에 접근하면 충돌 발생.
- 이를 방지하기 위해 상호 배제(Mutex)와 세마포어(Semaphore)를 사용.
- Buffer 의 구현
- 생산자 (Producer)
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define BUFFER_SIZE 3
int buffer[BUFFER_SIZE];
int in = 0, out = 0;
sem_t empty; // 빈 슬롯을 추적
sem_t full; // 채워진 슬롯을 추적
pthread_mutex_t mutex; // 상호 배제
void* producer(void* arg) {
int item;
for (int i = 0; i < 5; i++) {
item = i + 1; // 생산한 데이터
sem_wait(&empty); // 빈 슬롯 확인
pthread_mutex_lock(&mutex); // Critical Section 시작
buffer[in] = item;
printf("Producer produced: %d\n", item);
in = (in + 1) % BUFFER_SIZE;
pthread_mutex_unlock(&mutex); // Critical Section 종료
sem_post(&full); // 채워진 슬롯 증가
sleep(1);
}
return NULL;
}
void* consumer(void* arg) {
int item;
for (int i = 0; i < 5; i++) {
sem_wait(&full); // 채워진 슬롯 확인
pthread_mutex_lock(&mutex); // Critical Section 시작
item = buffer[out];
printf("Consumer consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
pthread_mutex_unlock(&mutex); // Critical Section 종료
sem_post(&empty); // 빈 슬롯 증가
sleep(1);
}
return NULL;
}
int main() {
pthread_t prod, cons;
sem_init(&empty, 0, BUFFER_SIZE); // 초기 빈 슬롯: 버퍼 크기
sem_init(&full, 0, 0); // 초기 채워진 슬롯: 0
pthread_mutex_init(&mutex, NULL);
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&mutex);
return 0;
}
Bounded-Buffer Problem 세마포어
- 문제 해결을 위한 세마포어
- Empty:
- 버퍼 내 빈 공간을 나타낸다
- 생산자가 데이터를 추가할 때 감소(P(empty)), 소비자가 데이터를 제거할 때 증가(V(empty)).
- 초기 값: n (버퍼의 총 크기).
- Full:
- 버퍼 내 채워진 데이터의 개수를 나타낸다
- 소비자가 데이터를 제거할 때 감소(P(full)), 생산자가 데이터를 추가할 때 증가(V(full)).
- 초기 값: 0 (비어있는 상태).
- Mutex:
- 버퍼 접근에 대한 Mutual Exclusion 를 보장한다.
- 생산자와 소비자가 동시에 버퍼를 수정하지 못하도록 보호.
- 초기 값: 1 (뮤텍스는 한 번에 한 프로세스만 접근 가능).
- Empty:
생산자 Process
do {
produce an item in nextp; // 데이터 생성
P(empty); // 빈 공간을 기다림
P(mutex); // Critical Section 보호
add nextp to buffer; // 버퍼에 데이터 추가
V(mutex); // Critical Section 종료
V(full); // 채워진 데이터 개수 증가
} while (1);
- 동작 과정
- 생산자는 새로운 데이터를 생성.
- P(empty):
- 버퍼에 빈 공간이 없으면 대기.
- 빈 공간이 있으면 감소.
- P(mutex): 버퍼 접근 권한을 얻기 위해 뮤텍스 대기.
- 데이터를 버퍼에 추가.
- V(mutex): 버퍼에서 빠져나옴(Critical Section 종료).
- V(full): 채워진 데이터의 개수를 증가.
- 위 작업을 반복.
소비자 Process
do {
P(full); // 데이터가 들어오기를 기다림
P(mutex); // Critical Section 보호
remove an item from buffer to nextc; // 버퍼에서 데이터 가져오기
V(mutex); // Critical Section 종료
V(empty); // 빈 공간 개수 증가
consume the item in nextc; // 데이터 소비
} while (1);
- 동작 과정
- P(full):
- 버퍼에 데이터가 없으면 대기.
- 데이터가 있으면 감소.
- P(mutex): 버퍼 접근 권한을 얻기 위해 뮤텍스 대기.
- 데이터를 버퍼에서 제거.
- V(mutex): 버퍼에서 빠져나옴(Critical Section 종료).
- V(empty): 빈 공간의 개수를 증가.
- 데이터를 소비.
- 위 작업을 반복.
- P(full):
- 예시
- 생산자 1:
- 데이터 생성 → P(empty)로 빈 공간 확인 (empty = n-1).
- 버퍼에 데이터 추가 → P(mutex)로 뮤텍스 잠금.
- V(mutex) → Critical Section 종료.
- V(full) → 채워진 슬롯 증가 (full = 1).
- 소비자 1:
- P(full) → 데이터가 있는지 확인 (full = 0).
- P(mutex)로 뮤텍스 잠금 후 데이터 제거.
- V(mutex) → Critical Section 종료.
- V(empty) → 빈 공간 증가 (empty = n).
- 생산자 1:
2. Readers-Writers Problem
- 문제 정의
- 여러 Reader(읽기 프로세스)와 Writer(쓰기 프로세스)가 동일한 데이터에 접근하려 할 때 데이터의 무결성과 동기화를 유지하는 문제.
- 목표:
- 여러 Reader는 동시에 데이터를 읽을 수 있음.
- Writer는 단독으로 데이터를 수정해야 함 (읽거나 쓰는 중에 다른 작업 불가).
- Reader와 Writer가 동시에 데이터에 접근하면 안 됨.
Readers-Writers Problem Solution 1
- 문제 해결을 위한 자료구조와 세마포어
- int Readcount:
- 현재 데이터를 읽고 있는 Reader의 수를 저장.
- 첫 번째 Reader가 진입하면 Writer를 차단.
- Semaphore Wrt:
- Writer 간의 동기화를 보장.
- Writer가 작업 중일 때 Reader와 다른 Writer의 접근을 차단.
- Semaphore Mutex:
- Readcount 와 wrt 에의 접근이 원자적으로 수행됨을 보장하기 위한 세마포어
- int Readcount:
- 초기값
- Mutex = 1: Reader가 Readcount를 안전하게 수정 가능.
- Wrt = 1: Writer의 접근 제어.
- Readcount = 0: 초기에는 Reader가 없음.
Writer Process
P(wrt); // Writer가 진입. 다른 Writer와 Reader 차단
// Critical Section
writing is performed; // 데이터 쓰기 작업 수행
V(wrt); // Writer가 작업 완료. 접근 해제
- 작동 원리
- Writer가 P(wrt)를 호출하여 Critical Section에 진입.
- 데이터 쓰기 작업이 끝나면 V(wrt)를 호출하여 Critical Section을 나감.
Reader Process
P(mutex); // Readcount에 대한 상호 배제 보호
readcount++; // Reader 수 증가
if (readcount == 1)
P(wrt); // 첫 번째 Reader가 진입 시 Writer 차단
V(mutex); // Readcount 수정 완료
// Critical Section
reading is performed; // 데이터 읽기 작업 수행
P(mutex); // Readcount에 대한 상호 배제 보호
readcount--; // Reader 수 감소
if (readcount == 0)
V(wrt); // 마지막 Reader가 나가면 Writer 허용
V(mutex); // Readcount 수정 완료
- 작동 원리
- P(mutex)로 Readcount 보호.
- Readcount++: 첫 번째 Reader가 진입하면 P(wrt)를 호출하여 Writer를 차단.
- Critical Section에서 데이터를 읽음.
- Reader가 작업을 끝내고 나가면:
- Readcount--:
- 마지막 Reader가 나가면 V(wrt)를 호출하여 Writer를 허용.
- Readcount--:
- 작동 예시
- 초기값
- Readcount = 0, Mutex = 1, Wrt = 1
- 동작
- Reader 1 진입:
- P(mutex) → Readcount = 1.
- 첫 Reader이므로 P(wrt)로 Writer 차단.
- Critical Section에서 읽기 작업 수행.
- V(mutex).
- Reader 2 진입:
- P(mutex) → Readcount = 2.
- 이미 Writer는 차단되었으므로 P(wrt) 불필요.
- Critical Section에서 읽기 작업 수행.
- V(mutex).
- Reader 1 종료:
- P(mutex) → Readcount = 1.
- Writer는 여전히 차단 상태.
- V(mutex).
- Reader 2 종료:
- P(mutex) → Readcount = 0.
- 마지막 Reader이므로 V(wrt)로 Writer를 허용.
- V(mutex).
- Writer 진입:
- P(wrt) → Writer가 Critical Section에 진입.
- Writer 작업 수행 후 V(wrt)로 종료.
- Reader 1 진입:
- 초기값
- 문제점
- Writer 의 Starvation
- Readcount == 0 일 때만, V(wrt) 가 수행되어 P(wrt) 로 대기하고 있던 Writer 가 수행할 수 있음
- 첫 번째 Reader (Readcount == 1) 가 P(wrt) 만 통과하면, 다른 Reader 들은 P(mutex)에 대한 P(mutex) 만 기다리면, 언제든지 수행할 수 있기 때문에 Writer 와 상관없이 진입할 수 있음
- 여러 Reader 들이 계속해서 진입할 경우, Readcount 는 0까지 떨어지지 않을 수 있음
- Writer 의 Starvation
- 해결 (1)
- Writers Preference
- Writer가 데이터를 수정할 때 우선권을 가짐.
- 추가 변수
- int writecount
- 현재 Writer의 수를 추적하여 우선권을 부여.
- int writecount
- 문제
- Reader가 굶주릴(Starvation) 가능성이 있음.
- 구현
- Writers Preference
// Reader Process
P(mutex); // Readcount를 안전하게 수정하기 위해 뮤텍스 보호
while (writecount > 0) // Writer가 대기 중이면 진입 대기
wait();
readcount++; // 현재 Reader 수 증가
if (readcount == 1) // 첫 번째 Reader가 진입하면 Writer를 차단
P(wrt);
V(mutex); // Readcount 수정 완료
// Critical Section
reading is performed; // 데이터 읽기 작업 수행
P(mutex); // Readcount를 안전하게 수정하기 위해 뮤텍스 보호
readcount--; // Reader 수 감소
if (readcount == 0) // 마지막 Reader가 나가면 Writer 허용
V(wrt);
V(mutex); // Readcount 수정 완료
----------------------------------------------------------------------
// Writer Process
P(mutex); // writecount를 안전하게 수정하기 위해 뮤텍스 보호
writecount++; // Writer 수 증가
V(mutex);
P(wrt); // Writer가 Critical Section에 진입. Reader 차단
// Critical Section
writing is performed; // 데이터 쓰기 작업 수행
V(wrt);
P(mutex); // writecount를 안전하게 수정하기 위해 뮤텍스 보호
writecount--; // Writer 수 감소
if (writecount == 0)
signal(); // 대기 중인 Reader 허용
V(mutex);
- 해결(2)
- Fair Solution
- Reader와 Writer 중 먼저 요청한 프로세스에 우선권을 부여.
- Reader와 Writer가 공정하게 실행되므로 Starvation 문제를 방지.
- 필요한 자료구조
- Queue: Reader와 Writer 요청을 관리.
- 구현 아이디어
- Reader와 Writer가 요청을 Queue에 삽입.
- Queue에서 요청 순서대로 Critical Section에 접근.
- 한 번에 하나의 Writer 또는 여러 Reader가 접근 가능.
- 구현
- Fair Solution
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_READERS 5
#define NUM_WRITERS 3
sem_t queue; // 공정한 순서를 보장하기 위한 세마포어
sem_t wrt; // Writer 접근 제어
sem_t mutex; // Reader 수 조작 보호
int readcount = 0; // 현재 읽고 있는 Reader 수
// Reader 프로세스 함수
void* reader(void* arg) {
int id = *((int*)arg);
while (1) {
sem_wait(&queue); // 공정한 순서를 보장하기 위해 대기
sem_wait(&mutex); // Reader 수를 안전하게 증가
readcount++;
if (readcount == 1)
sem_wait(&wrt); // 첫 번째 Reader가 Writer를 차단
sem_post(&mutex); // Reader 수 수정 완료
sem_post(&queue); // 다음 프로세스에 접근 허용
// Critical Section (읽기 작업)
printf("Reader %d is reading\n", id);
sem_wait(&mutex); // Reader 수를 안전하게 감소
readcount--;
if (readcount == 0)
sem_post(&wrt); // 마지막 Reader가 나가면 Writer 허용
sem_post(&mutex); // Reader 수 수정 완료
}
return NULL;
}
// Writer 프로세스 함수
void* writer(void* arg) {
int id = *((int*)arg);
while (1) {
sem_wait(&queue); // 공정한 순서를 보장하기 위해 대기
sem_wait(&wrt); // Writer가 Critical Section에 진입
sem_post(&queue); // 다음 프로세스에 접근 허용
// Critical Section (쓰기 작업)
printf("Writer %d is writing\n", id);
sem_post(&wrt); // Writer 작업 완료
}
return NULL;
}
int main() {
pthread_t r_threads[NUM_READERS], w_threads[NUM_WRITERS];
int r_ids[NUM_READERS], w_ids[NUM_WRITERS];
// 세마포어 초기화
sem_init(&queue, 0, 1); // 하나씩 순서를 보장
sem_init(&wrt, 0, 1); // Writer 접근 제어
sem_init(&mutex, 0, 1); // Reader 수 조작 보호
// Reader 스레드 생성
for (int i = 0; i < NUM_READERS; i++) {
r_ids[i] = i + 1;
pthread_create(&r_threads[i], NULL, reader, &r_ids[i]);
}
// Writer 스레드 생성
for (int i = 0; i < NUM_WRITERS; i++) {
w_ids[i] = i + 1;
pthread_create(&w_threads[i], NULL, writer, &w_ids[i]);
}
// 스레드가 종료되지 않도록 대기
for (int i = 0; i < NUM_READERS; i++) {
pthread_join(r_threads[i], NULL);
}
for (int i = 0; i < NUM_WRITERS; i++) {
pthread_join(w_threads[i], NULL);
}
// 세마포어 해제
sem_destroy(&queue);
sem_destroy(&wrt);
sem_destroy(&mutex);
return 0;
}
- 동작 원리
- queue 세마포어:
- 모든 Reader와 Writer의 공정성을 보장.
- Reader와 Writer가 FIFO 순서로 실행되도록 제어.
- mutex 세마포어:
- readcount 변수를 보호하여 Race Condition을 방지.
- Reader 수를 안전하게 증가/감소.
- wrt 세마포어:
- Writer 간의 상호 배제 및 Reader와 Writer의 동기화를 보장.
- queue 세마포어:
- 결과
- Reader와 Writer의 공정성:
- Reader와 Writer는 FIFO 순서로 실행됨
- Writer가 대기 중이라면 Reader는 작업을 마친 후 Writer에 우선권을 부여.
- Writer와 Reader의 작업이 공정하게 수행됨.
- Reader와 Writer의 공정성:
- 실행 예시
Reader 1 is reading
Reader 2 is reading
Reader 3 is reading
Reader 4 is reading
Reader 5 is reading
Writer 1 is writing
Reader 1 is reading
Writer 2 is writing
Reader 2 is reading
Writer 3 is writing
...
3. Dining-Philosophers Problem
- 문제 정의
- 5명의 철학자가 원탁에 앉아 있으며, 각 철학자 사이에는 젓가락이 하나씩 놓여 있음.
- 고전적인 Concurrency Method
- 철학자는 생각(thinking)하거나, 먹기(eating)를 수행.
- 젓가락이 5개 뿐
- 이웃한 젓가락만 집을 수 있음
- 두 젓가락을 모두 집어야 식사 가능
- 식사를 하고 난 다음에야 두 젓가락을 모두 내려놓을 수 있음
- Deadlock 과 Starvation 이 발생하는 경우
- 모두 자신의 오른쪽 젓가락을 집었을 경우
- 이로 인해 모든 철학자가 젓가락을 기다리면서 무한 대기 상태에 빠짐.
- 모두 자신의 오른쪽 젓가락을 집었을 경우
Dining-Philosophers Problem Solution 1
- 단순히 젓가락을 집는 것에 대한 동기화를 부여하는 방법
- 모든 철학자가 자신의 왼쪽 또는 오른쪽 젓가락부터 집도록 한다.
- boolean waiting[n] = 1
- 세마포어
- chopstic[5] = 1: 각각의 젓가락에 대한 동기화 관리
철학자 Process
do {
think(); // 생각
P(chopstick[i]); // 왼쪽 젓가락 집기
P(chopstick[(i + 1) % 5]); // 오른쪽 젓가락 집기
eat(); // 먹기
V(chopstick[i]); // 왼쪽 젓가락 놓기
V(chopstick[(i + 1) % 5]); // 오른쪽 젓가락 놓기
} while (1);
- 문제점
- Deadlock 발생 가능:
- 모든 철학자가 동시에 젓가락을 집으면, 각자 한 개의 젓가락을 가지고 대기 상태에 빠짐.
- Deadlock 발생 가능:
- 해결
- 한 번에 최대 4명의 철학자만 식사에 참여 가능.
- 양 쪽 젓가락이 모두 사용 가능할 때만 젓가락을 집도록 함
- 홀수 번호 철학자는 왼쪽 젓가락부터 잡고, 짝수 번호 철학자는 오른쪽 젓가락부터 잡음
- 위의 해결방안들은 Starvation 까지 해결해주지는 못함
- 각각의 방안에 대해 Starvation 에 대한 고려를 추가할 수 있음
ex) 한 차례 굶은 철학자에게 우선권을 줌
- 각각의 방안에 대해 Starvation 에 대한 고려를 추가할 수 있음
Dining-Philosophers Problem Solution 2
- 문제 해결 접근 방식
- 철학자가 자신의 상태와 양쪽 젓가락의 상태를 확인 후, 양쪽 젓가락을 집거나 대기.
- 동시에 두 젓가락을 집을 수 있도록 상태와 동기화를 관리.
- 사용되는 자료구조
- State 배열:
- State[5]: 각 철학자의 현재 상태를 저장.
- THINKING: 생각 중.
- HUNGRY: 젓가락을 잡고 싶어함.
- EATING: 젓가락을 잡고 먹는 중.
- State[5]: 각 철학자의 현재 상태를 저장.
- Mutex: 젓가락을 집거나 놓는 수행을 Critical Section 으로 관리하기 위한 세마포어. (초기값 : 1)
- Self 배열:
- Self[5] : 철학자 각각이 젓가락 두 개를 집기를 기다리는 세마포어 (초기값 : 0)
- 철학자 i 가 HUNGRY 상태이더라도, 다른 젓가락 하나를 사용할 수 없을 경우 Waiting 을 하기 위한 세마포어
- Self[5] : 철학자 각각이 젓가락 두 개를 집기를 기다리는 세마포어 (초기값 : 0)
- State 배열:
철학자 Process
do {
think(); // 생각
take_chopsticks(i); // 젓가락을 집기
eat(); // 먹기
put_chopsticks(i); // 젓가락을 내려놓기
} while (1);
void take_chopsticks(int i) {
P(mutex); // 상태 변경 및 테스트 보호
state[i] = HUNGRY; // 철학자 상태를 HUNGRY로 설정
test(i); // 자신이 EATING으로 전환 가능한지 테스트
V(mutex); // 상태 변경 작업 완료
P(self[i]); // 자신이 EATING 상태가 될 때까지 대기
}
- 동작 과정
- 목적: 젓가락을 잡기 전 조건 확인 및 대기.
- 구현 논리:
- Mutex를 통해 동기화 시작:
- state[i]를 HUNGRY로 설정.
- test(i)를 호출하여 철학자가 식사 가능한 상태인지 확인.
- 식사 불가능한 경우: self[i] 세마포어를 통해 대기 상태로 전환.
- 식사 가능 상태: self[i] 신호를 받아 EATING 상태로 진입.
- Mutex를 통해 동기화 시작:
void put_chopsticks(int i) {
P(mutex); // 상태 변경 및 테스트 보호
state[i] = THINKING; // 철학자 상태를 THINKING으로 설정
test(LEFT); // 왼쪽 철학자가 EATING 상태로 전환 가능한지 테스트
test(RIGHT); // 오른쪽 철학자가 EATING 상태로 전환 가능한지 테스트
V(mutex); // 상태 변경 작업 완료
}
- 동작 과정
- 목적: 식사를 마치고 젓가락을 내려놓음.
- 구현 논리:
- Mutex를 통해 동기화 시작:
- 철학자의 상태를 THINKING으로 전환.
- 왼쪽(LEFT)과 오른쪽(RIGHT) 철학자의 상태를 확인.
- test() 호출:
- 왼쪽과 오른쪽 철학자가 젓가락을 사용할 수 있다면 신호를 보내 EATING 상태로 전환.
- 왼쪽과 오른쪽 철학자가 젓가락을 사용할 수 있다면 신호를 보내 EATING 상태로 전환.
- Mutex를 통해 동기화 시작:
void test(int i) {
if (state[i] == HUNGRY && // 현재 철학자가 HUNGRY 상태이고
state[LEFT] != EATING && // 왼쪽 철학자가 EATING 중이 아니며
state[RIGHT] != EATING) { // 오른쪽 철학자가 EATING 중이 아닐 때
state[i] = EATING; // 철학자 상태를 EATING으로 변경
V(self[i]); // 철학자에게 신호를 보내 EATING 상태로 전환
}
}
- 동작 과정
- 목적: 젓가락 상태를 확인하고 철학자가 식사 가능한지 결정.
- 구현 논리:
- 철학자가 HUNGRY 상태이고, 왼쪽과 오른쪽 철학자가 EATING 중이 아닐 경우:
- 철학자의 상태를 EATING으로 전환.
- 철학자 자신에게 신호를 보내 대기에서 해제.
- 철학자가 HUNGRY 상태이고, 왼쪽과 오른쪽 철학자가 EATING 중이 아닐 경우:
- 전체적인 동작 과정
- 철학자가 식사를 시작하는 경우:
- take_chopsticks(i) 호출.
- 상태를 HUNGRY로 변경 후, 좌우 젓가락 상태 확인.
- 좌우 젓가락이 사용 가능하면 식사 시작(EATING 상태).
- 철학자가 식사를 끝내는 경우:
- put_chopsticks(i) 호출.
- 상태를 THINKING으로 변경 후, 좌우 철학자의 상태 확인.
- 좌우 철학자가 식사 가능하다면 신호를 보내 식사 시작.
- 철학자가 식사를 시작하는 경우:
- 해설
- 철학자 좌우 젓가락이 사용 가능할 때만 Critical Section 에 진입함
- i 번째 철학자가 식사를 하기 위해서는 i-1 과 i+1 철학자가 EATING 상태가 아니어야 함
- 철학자 좌우 젓가락이 사용 가능할 때만 Critical Section 에 진입함
- check 요소
- Data Consistency: 상태(State) 배열과 세마포어를 통해 데이터 일관성 보장.
- Deadlock 방지: 철학자가 식사 가능한 경우에만 Critical Section에 진입하도록 설계.
- Starvation 가능성: 해결되지 않을 수 있음. Starvation 방지 메커니즘 추가 가능.
- Concurrency: 여러 철학자가 동시에 작업을 수행 가능.
반응형
'3학년 2학기 학사 > 운영체제' 카테고리의 다른 글
[운영체제] #10. Memory Management (2) (0) | 2024.12.01 |
---|---|
[운영체제] #10. Memory Management (1) (0) | 2024.12.01 |
[운영체제] #9. 동기화 (1) (0) | 2024.11.27 |
[운영체제] #7. InterProcess Communication (IPC) (0) | 2024.11.26 |
[운영체제] #5. Computer Architecture (0) | 2024.11.24 |