운영체제
32 병행성 관련 버그
오류의 종류
병행성 문제는 공통된 패턴을 가지고 있다
공통적 병행성 문제
- 정확한 병행적 프로그램을 작성하긴 어렵다
- 데드락 문제
- 데드락이 아닌 문제
데드락(교착상태)
- 두개 이상 동작이 서로 기다리길 기다리는 상태
스레드 1이 락1을 가지고 있고 락 2를 원하고
스레드 2는 락 2를 지니고 락 1을 원한다
각 스레드가 상대가 소유하는 락을 대기하기 때문에 시스템이 멈춘다
데드락 발생 조건
4가지 경우가 데드락을 일으킴
- mutual exclusion 상호 배제
- 스레드가 자신이 필요하는 자원에 대해 독점을 주장
- hold and wait 점유 및 대기
- 스레드는 자신에게 할당된 락을 점유한채로 다른 락을 대기한다
- no preemption 비 선점
- 락을 지닌 쓰레드로부터 강제적으로 락을 뺏을 수 없다
- circular wait 환형 대기
- 각 쓰레드는 다음 쓰레드가 요청한 락을 갖고있는 쓰레드들의 순환 고리가 있따
이 4가지 조건 중 하나라도 만족하지 않는다면 데드락은 일어나지 않는다
왜 데드락이 발생하는가
- 구성 요소간에 복잡한 의존성이 발생하기 때문
- 캡슐화의 성질 때문
- 소프트웨어의 자세한 디테일을 숨기게 모듈화
- 모듈화와 락은 조화가 잘 되지 않는다
데드락 예방
lock ordering - circular wait
순환 대기를 피하기 위해 락 획득을 하는 순서를 정한다
단점
Global lock - hold and wait
점유 및 대기를 피하기 위해 모든 락을 원자적으로 획득한다
- 락 획득 중에 시기적절한 스레드 교환이 발생하지 않도록 보장
장점
- 데드락과 관계없이 락 획득 순서를 가능하게 한다
단점
- 필요한 락들을 정확히 파악해야한다
- 병행성이 저하된다
trylock - no preemption
문제!!
여러 락을 보유한 상태에서 추가로 락을 요청할 경우 문제 발생할 여지가 있다
trylock()
- 락이 획득가능하면 락을 획득
- 획득을 못하면 필요한 락 모두 포기
새로운 문제
livelock 무한 반복
- 두개의 스레드가 락을 얻으려고 하지만 두 쓰레드 모두 계속해서 락을 못 얻을 수 있다
- 진행이 안되고 무한 반복된다
- 해결법
스케줄링으로 데드락 피하기
- 데드락 예방대신 피하는 것이 유용할 때가 있다
- 오직 모든 작업과 락들을 알고 있을 때 가능하다
- 각 프로세서가 요청하는 작업들을 알고 같이 못 실행시키게 스케줄 한다