🗺️ Thread Safe
Thread safe: 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수/변수/객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음
- 하나의 함수가 한 스레드로부터 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하여 동시에 함께 실행되더라도 각 스레드에서의 함수의 수행 결과가 올바로 나옴
🗺️ Thread Safe 보장하는 방법
- Re-entrancy, 재진입성
어떤 함수가 한 스레드에 의해 호출되어 실행 중일 때 다른 스레드가 그 함수를 호출하더라도 각각의 결과가 올바름
- 스레드 호출과 상관없이 프로그램에 문제 X
- 스레드끼리 독립적으로 동작하도록 코드 작성
-
Thread-local storage, 스레드 지역 저장소
공유 자원의 사용은 최대한 줄임 > 각각의 스레드에서만 접근 가능한 저장소 사용 > 동시 접근 방지
-
Mutual exclusion, 상호 배제
공유 자원을 꼭 사용해야 할 경우 해당 자원의 접근을 세마포어 등의 락으로 통제
-
Atomic operation, 원자 연산
공유 자원에 접근할 때 원자 연산 또는 원자적으로 정의된 접근방법을 사용하여 상호 배제 구현
- 공유 자원 변경에 필요한 연산을 원자적으로 분리한 뒤 실제로 데이터 변경이 이루어지는 시점에 lock을 걸고 데이터를 변경하는 시간 동안 다른 스레드의 접근 막음
- 원자 연산: 분리할 수 없고 다른 스레드에 의해 중단될 수 없는 작업
- (예) a += b: + 연산 수행 후 = 연산 수행
🗺️ Peterson's Algorithm
피터슨 알고리즘: flag & turn 변수로 임계영역에 들어갈 프로세스/스레드를 결정
- 공유 메모리 활용
- 여러 프로세스가 하나의 자원을 함께 사용할 때 문제가 발생하지 않도록
- flag: 프로세스 중 누가 임계영역에 진입할 것인지
- turn: 누가 임계영역에 들어갈 차례인지
임계구역 해결조건 3가지 만족
- 상호 배제: 임계구역에 한번에 2개 이상의 프로세스/스레드가 접근하지 못하도록 해야 함
- 각 프로세스는 자신의 순서여야만 공유 자원에 접근할 수 있음
- turn 변수의 사용: turn 변수의 값이 동시에 두개일 수 없음 (0이면서 1일 수 없음)
- 진행: 임계구역에 어떤 스레드도 실행되고 있지 않다면 실행 요청하는 스레드가 있을 경우 바로 접근 가능
- 임계구역에 접근한 프로세스는 실행 완료 후 exit하면서 flag을 false로 바로 만듬
- i번째 프로세스는 실행 완료 이후
flag[i]
를 false
로 만듬
- 한정대기 (bounded waiting): 자원을 요청하는 프로세스가 영원히 대기하지 않게 하는 것
flag[j]
가 0이 되면서 적어도 한번은 i번째 프로세스가 실행할 수 있게 함
한계점: Busy waiting
- 각 프로세는 CPU 스케쥴링에 의해 진행됨
- 임계 영역에 들어가기 위해 기다리고 있는 프로세스는 무한루프를 돌며 임계 영역 직전에 머무르게 됨
- 이 무한 루프에 CPU 자원이 쓰이고 있음
- 운영체제의 목표: CPU를 효율적으로 활용하는 것
🗺️ Race Condition
Race condition:
- 두 개 이상의 프로세스가 공통 자원을 병행적으로 읽거나 쓸 때, 공용 데이터에 대한 접근의 순서 때문에 프로그램 등의 실행/출력 결과가 일정하지 않음
- 3가지 제어 문제:
- Mutual exclusion
- race condition을 막기 위해서 두개 이상의 프로세스가 공용 데이터에 동시 접근하는 것을 막아야 함
- Deadlock
- 상호 배제 시행 > 교착 상태 가능성
- 프로세스가 각자 프로그램을 실행하기 위해 두 자원 모두 필요할 때 프로세스는 필요한 두 자원 모두를 사용하여 수행할 때까지 이미 소유한 리소스를 해제하지 않음
- 교착 상태
- Starvation
- 프로세스들이 더이상 진행하지 못하고 영구적으로 블록
- 시스템 자원 경쟁, 프로세스 간 통신과정 등에서 발생
- 두 개 이상의 작업이 서로 상대방의 작업이 끝나기만을 기다리고 있음 > 결과적으로 아무것도 완료되지 못함
세마포어와 뮤텍스로 예방
참고: