=> 동시성 문제는 비교착상태, 교착상태 이 두 가지로 나뉜다.
1. 비교착 상태 문제
1-1. 원자성 위반 오류
=> 원자성 위반 오류는 문맥 교환이 발생하지 않을 것이라 생각하여 발생한다.
=> 단순 +1 연산이라도, OS 단에서는 3가지의 명령으로 또 나뉠 수 있다.
=> 이러한 과정을 생각하지 못했을 때 발생하는 오류가 원자성 위반 오류이다.
Thread 1
=> if 문으로 NULL이 아님을 확인한다.
=> fputs 함수는 proc_info를 참조한다.
Thread 2
=> proc_info를 NULL로 한다.
=> 이제 이 과정을 섞어보자.
=> 실제로 문맥 교환은 언제 어디서 일어날 줄 모른다.
Thread 1
=> if 문으로 NULL이 아님을 확인한다.
Thread 2
=> proc_info를 NULL로 한다.
Thread 1
=> fputs 함수는 proc_info를 참조한다.
=> NULL 참조 크래시!!!
1-1.1. 원자성 위반 오류 해결법
=> 원자성 위반 오류는 그저 원자성만 책임져주면 해결된다.
=> 락을 통해 원자성을 책임져 줄 수 있다.
=> 락 프리 CAS(낙관적)을 이용하여, 원자성 오류가 나타났을 때, 오류가 나타나지 않을 때까지 다시 시도해준다.
=> 아예 원자적 연산을 수행해버린다.
=> 이러한 방법들이 있다.
1-2. 순서 위반 오류
=> 순서 위반 오류는 연산들이 특정 순서로 차례대로 실행될 것이라고 생각할 때 발생한다.
=> 앞서 말했지만, 쓰레드를 다룸에 있어 가장 중요한 것은 쓰레드는 실행되는 순서를 알 수 없는 비 결정형 형태라고 생각해야 한다.
1-2.1. 순서 위반 오류 해결법
=> 컨디션 변수를 통해 wait과 signal을 적절히 보내줘야 한다.
=> 즉, 쓰레드 간 특정 연산의 순서를 보장하고 싶으면, wait과 signal이 필요하다는 것이다.
=> 자바에서는 Synchronized 블록 안에서 wait()/notify()를 사용할 수 있다.
2. 교착 상태 문제
2-1. 교착 상태가 발생하는 이유
2-1-1. 2개 이상의 공통으로 접근할 수 있는 메모리와 2개 이상의 쓰레드
=> 웹에서는 웬만해서는 이 조건을 만족할 것이다.(DB 레코드들 + 세션들)
2-1-2. 상호 배제
=> 쓰레드가 락을 획득하여 다른 쓰레드가 실행되지 못하게 한다.
2-1-3. 점유 및 대기
=> 쓰레드가 락을 반납하지 않고, 획득하려 시도한다.
2-1-4. 비 선점
=> 자원을 강제로 뻇을 수 없다.
2-1-5. 순환 대기
=> 락을 갖고 있는 쓰레드들의 순환 고리가 있다.
2-1-6. 추상화
=> 락에 대해 감추고 있기 때문에, 락의 발생 지점을 알아내기 어렵다.
2-2. 교착 상태 해결
=> 아래에 나온 1,2,3,4 방식 중 하나를 선택해 교착 상태를 방지할 수 있다.
2-2-1. 순환 대기 해결
=> 순환 대기는 락을 갖고 있는 쓰레드들의 순환 고리가 있기 때문이다.
=> 때문에, 쓰레드의 락 획득 순서를 일치시켜준다면, 이는 자연스럽게 해결이 될 것이다.
2-2-2. 점유 및 대기 해결
=> 획득하지 않은 락을 획득하고, 갖고 있는 락을 반납하려 할 때 일어난다.
=> 때문에, 락을 한 번에 가져오는 방법으로 해결해줄 수 있다.
=> MySQL에서는 Shared-Lock을 걸고 Exclusive-Lock을 거는 것이아닌,
=> 바로 Exclusive-Lock을 거는 방식으로 해결할 수 있다.
=> 즉, 한 번에 모든 락을 획득하는 것은, 하나의 락만 사용하는 것과 같다.
2-2-3. 비선점 해결
=> 비선점 해결법은 tryLock()이라는 함수에 있다.
=> 락을 획득하지 못하면, -1이라는 값을 반환하는데,
=> 이때, tryLock()을 통해 -1이 반환되면, 그냥 넘어가거나, 재시도를 할 수 있다.
=> 하지만, 확률은 매우매우 낮지만, 오묘하게 문맥교환 시기가 일치하면, 무한 반복을 할 수 있다.
=> 롤백에 대해 책임져야 한다.
2-2-4. 상호 배제 해결
=> CAS로 해결할 수 있다.(낙관적 락처럼)
https://icanchangeworld.tistory.com/156
CAS, 낙관적 락, Atomic VS LongAdder(Accumulator)
이 글은 Lock-Free 방식 중 하나를 설명한다. 1. CAS 기법이란=> 가정1: CompareAndSwap함수는 원자적으로 실행된다고 가정한다.=> 가정2: ptr은 모든 프로세서가 공유할 수 있는 Volatile 메모리이다. 1. 일단,
icanchangeworld.tistory.com
2-2-5. 교착 상태 회피(스케쥴링)
2-2-6. 발견 및 복구
'성능 최적화' 카테고리의 다른 글
코드(메서드) 리팩터링 가이드 (0) | 2025.05.10 |
---|---|
JOIN 최적화 (0) | 2025.04.24 |
비관 락, 컨디션 변수, 세마포어, 블록 (0) | 2025.04.21 |
트랜잭션 격리 수준과 락 (0) | 2025.04.20 |
CAS가 적용된 다양한 자바 클래스들 (1) | 2025.04.19 |