일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- PytestPluginManager
- VARCHAR (1)
- PersistenceContext
- preemption #
- tolerated
- Spring Batch
- 개성국밥
- mp4fpsmod
- 오블완
- vfr video
- JanusGateway
- 달인막창
- table not found
- JanusWebRTCGateway
- 헥사고날아키텍처 #육각형아키텍처 #유스케이스
- JanusWebRTC
- pytest
- Value too long for column
- 티스토리챌린지
- 코루틴 컨텍스트
- k8s #kubernetes #쿠버네티스
- terminal
- python
- kotlin
- 코루틴 빌더
- 깡돼후
- JanusWebRTCServer
- 자원부족
- 겨울 부산
- taint
너와 나의 스토리
[OS] CH32_Concurrency Bug: Deadlock 발생 조건 & 예방법 본문
32.2 Non-Deadlick bugs
non-deadlock bugs의 두가지 주요 타입: atomicity violation bugs and order violation bugs.
Atomicity-Violation Bugs
- atomicity violation: 코드는 atomic한데 실행시에는 그렇지 않음
- ex)
Thread 1::
if (thd->proc_info) {
fputs(thd->proc_info, ...);
}
Thread 2::
thd->proc_info = NULL;
thread1이 proc_info가 null이 아니여서 fputs()을 하려고 하는 직전에 interrupt가 되서 thread2가 실행되면,
thread2가 info가 null이 되고, thread1이 다시 이어 실행하면 info가 null인데 fputs()실행됨
- 해결책:
공유되는 변수 참조 주변에 lock 추가
pthread_mutex_t proc_info_lock = PTHREAD_MUTEX_INITIALIZER;
Thread 1::
pthread_mutex_lock(&proc_info_lock);
if (thd->proc_info) {
fputs(thd->proc_info, ...);
}
pthread_mutex_unlock(&proc_info_lock);
Thread 2::
pthread_mutex_lock(&proc_info_lock);
thd->proc_info = NULL;
pthread_mutex_unlock(&proc_info_lock);
Order-Violation Bugs
- order violation: A가 항상 B전에 실행되는데 순서가 실행 중에 강요되지 않은 경우
- 해결책:
condition variables 사용하기, lock 사용하기, state variable 사용
32.3 Deadlock Bugs
Thread 1: Thread 2:
pthread_mutex_lock(L1); pthread_mutex_lock(L2);
pthread_mutex_lock(L2); pthread_mutex_lock(L1);
thread1이 lock1을 잡고 lock2를 기다리는데, thread2가 lock2를 잡고 lock1을 기다리는 상황.
Deadlocks은 왜 발생하는가?
- 구성 요소들 사이에 복잡한 종속성이 발생
- encapsulation의 본질 때문에
modularity는 lock과 잘 맞지 않음
ex) java vector class & AddAll()
Vector v1,v2;
v1.AddAll(v2); // v2의 모든 데이터를 v1에 옮김
이 코드를 실행 중에 다른 thread가 v2.AddAll(v1) 실행하면 deadlock 발생함
Conditions for Deadlock
deadlock 발생 4가지 조건
- Mutual exclusion
- Hold-and-wait:
thread는 추가적인 자원(획득하려는 lock)을 얻기를 기다리는 동안 이미 보유한 자원(이미 획득한 lock)을 가지고 있는다
- No preemption:
자원들은 이를 획득한 thread로부터 제거되지 않는다.
- Circular wait:
각각의 thread들이 하나 이상의 체인의 다음 thread로부터 요청 받아지는 자원을 가지고 있는 circular chain이 존재
4조건 중 하나라 해당되지 않으면 deadlock은 발생하지 않음
Prevention
- Circular wait
해결책: lock획득의 total ordering를 제공
lock이 여러개이고 복잡한 시스템에서는 전체 순서 제공하는게 힘드므로 partial ordering 제공
ex) 메모리 매핑에서의 partial lock ordering
if (m1 > m2) { // grab in high-to-low address order
pthread_mutex_lock(m1);
pthread_mutex_lock(m2);
} else {
pthread_mutex_lock(m2);
pthread_mutex_lock(m1);
}
- Hold-and-wait
해결책: 모든 lock들을 한번에 얻기
pthread_mutex_lock(prevention); // begin acquisition
2 pthread_mutex_lock(L1);
3 pthread_mutex_lock(L2);
4 ...
5 pthread_mutex_unlock(prevention); // end
prevention lock 사이에서 thread switch 일어나지 않음을 보장
문제점:
1. 구현할 때, 어떤 lock들이 필요한지 미리 알아야 함 -> 어렵
2. 동시에 작업하기 힘들어짐 -> concurrency 감
- No Preemption
해결책: pthread_mutex_trylock() 같이 계속 lock을 기다리지 않고 리턴하는 방식 이용
pthread_mutex_lock(L1);
if (pthread_mutex_trylock(L2) != 0) {
pthread_mutex_unlock(L1);
goto top;
}
L1을 얻고 L2를 얻으려는데 못 얻으면 L1도 포기하고 돌아감 (다음에 다시 시도)
문제점:
- livelock
두 개의 thread가 반복적으로 이 시퀀스 시도하고 둘 다 실패하는 것을 반복하면 진행되지 않음
예를 들어, T1이 L1을 얻고 L2를 얻으려고 시도했는데 T2가 가지고 있어서 포기하고 L1도 놓고 돌아감
이 때, T2는 L2를 얻고 L1을 얻으려는데 T1이 가지고 있어서 포기하고 L2도 놓고 돌아감
다음에 또 동시에 T1은 L1, T2는 L2 먼저 잡게되면 이 루틴이 계속 반복되어 진행되지 않
- Mutual Exclusion
해결책: 상호 배제의 필요성을 없애기. 강력한 하드웨어 명령어를 사용하여, lock이 필요없는 데이터 구조 만들기
ex) CompareAndSwap(int *address, int expected, int new);
Scheduling을 통한 Deadlock 해결
ex1)
T1 T2 T3 T4
L1 yes yes no no
L2 yes yes yes no
ㄴ T1(thread)이 L1,L2 (lock) 필요로 함...
이 경우 영리한 스케쥴러라면 T1, T2를 동시에 실행시키지 않음 -> deadlock 발생 안함
ex2)
T1 T2 T3 T4
L1 yes yes yes no
L2 yes yes yes no
Detect and Recover
deadlock을 일시적으로 허용해주고, deadlock을 탐지해서 조취 취하기
'Operating System' 카테고리의 다른 글
OS-[CH39_Files and Directories] (0) | 2019.06.02 |
---|---|
[OS] CH31_Semaphores: lock과 condition variables을 대신해서 어떻게 semaphores을 쓸까? (0) | 2019.05.20 |
[OS] CH28_Locks: Critical section / Lock 방법 비교 (0) | 2019.05.13 |
OS - [CH20_Advanced page tables] (0) | 2019.04.14 |
OS - [CH18_Paging] (0) | 2019.04.07 |