세마포어
세마포어는 운영체제에서 서로 다른 태스크들이 동시에 하나의 장치 내의 실행 시간, 작업 권한 등의 자원(Resource)을 사용하려고 할 경우 작업 충돌을 피하기 위해 개발된 개념이다. 다익스트라 알고리즘으로 유명한 에츠허르 다익스트라가 처음 제시했다.
상세
세마포어는 특정한 전역 정수 변수(카운터)가 0이 될 때 특정 자원을 사용 중인 태스크(또는 태스크들) 외의 태스크들은 자원에 접근하지 못하게 한다. 세마포어에 접근하는 락 메서드는 카운터가 0이 아니라 1만큼 내릴 수 있으면 카운터를 내리고 접근한 프로세스를 기록하며, 이미 0이어서 내릴 수 없는 경우 해당 태스크의 실행을 일시 중지하고 기다린 다음 다시 락을 잡게 한다. 락을 걸기만 하고 풀지 않으면 자원 관리 체계가 꼬이는 참사가 나기 때문에 락 메서드를 건 태스크는 작업 종료 전 카운터를 다시 올려주는 해제 메서드를 반드시 호출해야 한다.
세마포어 락의 기준이 되는 카운터의 최대값이 1인 이진 세마포어의 경우(즉 한 번 잡으면 즉시 자원에 대한 접근이 막히는 경우)를 Mutual Exclusion의 약칭인 Mutex(뮤텍스)라고도 한다. 보통 단일 자원에 세마포어 락을 필요로 하는 경우가 많아 아예 이런 별칭까지 나올 정도로 자주 쓰인다.
교착 상태(Deadlock)
서로 의존성이 있는 둘 이상의 자원에 둘 이상의 태스크가 동시 접근하는 경우 자원들에게 임의의 순서로 세마포어를 걸었다가 작업 완료를 위해 사용해야 하는 또 다른 자원을 서로 걸은 세마포어 락 때문에 사용하지 못하는 데드락(교착 상태)가 발생한다.
교착 상태의 경우 상호 배제로 한 번에 하나만 자원을 쓸 수 있으며, 자원을 쓰는 동안 또 다른 자원을 잡아야 하며, 강제로 자원을 빼앗아올 방법이 없고, 서로가 서로가 가진 자원을 가져가야 하는 순환 대기가 있어야 발생한다. 따라서 4가지 중 하나를 부수어야 교착 상태가 풀린다.
가장 좋은 방법으로 여러 개의 같은 자원를 잡는 태스크들은 반드시 자원의 세마포어 락을 잡고 푸는 순서를 일치시켜야 한다. 이건 교착 상태에 대한 대책 중 avoid 방식에 해당한다.