-
반응형
스핀락과 더불어 커널에서 가장 많이 쓰이는 동기화 기법은 뮤텍스(mutex)이다. 뮤텍스는 휴면을 지원하며 프로세스 컨텍스트에서 주로 쓰는 동기화 기법이다.
1. 뮤텍스의 기본 개념
뮤텍스는 상호 배제(mutual exclusion)의 약자로서 임계 영역에 한 개의 프로세스만 접근하는 동기화 기법이다. 뮤텍스는 사실 리눅스 커널에서만 쓰이는 동기화 기법은 아니다. 뮤텍스는 운영체제에서 쓰는 용어이다. '임계 영역에 2개의 프로세스가 동시에 접근하지 못하도록 막는 기법'으로서 각 운영체제마다 다르게 구현돼 있다.
뮤텍스 기본 동작을 스핀락과 비교
뮤텍스를 스핀락과 비쇼했을 때 가장 큰 차이점은 잠금쇠가 잠겨 있을 때 기다리는 방식이다. 프로세스는 뮤텍스를 획득하지 못하면 휴면 상태로 진입한다. 물론 휴면에 진입하기 전에 뮤텍스 대기 리스트에 자신을 등록한다. 즉, 휴면 상태에 진입하면서 뮤텍스를 기다리는 것이다. 임계 영역을 실행하고 난 다음 A 프로세스는 자신이 획득한 뮤텍스를 해제한다. 이때 뮤텍스를 기다리는 프로세스가 있는지 확인한다. A 프로세스는 B프로세스가 뮤텍스를 획득하지 못하고 휴면 상태에 진입했다는 사실을 뮤텍스의 대기 리스트를 보고 알게 된다. 이후 A 프로세스는 B 프로세스를 깨운다. 그러면 뮤텍스를 기다리면서 잠든 B 프로세스는 깨어나 뮤텍스를 획득한 후 임계 영역을 실행한다. 정리하면 뮤텍스를 스핀락 기법과 비교하면 다음 동작이 다르다.
- 뮤텍스 획득 : 이미 뮤텍스를 다른 프로세스가 획득했으면 휴면 상태로 진입
- 뮤텍스 해제 : 뮤텍스를 기다리며 휴면 상태에 진입한 프로세스를 깨움
뮤텍스를 써서 임계 영역을 보호하는 예제 코드 분석
mutex_lock() 함수와 mutex_unlock() 함수를 볼 수 있다. gov_update_sample_delay() 함수가 임계 영역인데 이 함수를 한 개의 프로세스만 실행하도록 뮤텍스를 써서 보호한것이다. 정리하면 mutex_lock() 함수는 뮤텍스를 획득하고 mutex_unlock() 함수는 획득한 뮤텍스를 해제하는 기능이다. 어떤 프로세스가 뮤텍스를 획득한 수 코드를 수행하는 동안 다른 프로세스는 함수를 수행할 수 없다. 대신 mutex_lock() 함수 내부에서 휴면 상태로 진입하면서 뮤텍스를 기다리게 된다.
뮤텍스 자료구조
mutex 구조체에서 중요한 필드를 소개한다.
- atomic_long_t owner
뮤텍스를 획득한 프로세스의 태스크 디스크립터 주소를 저장한다. owner 필드를 보고 뮤텍스가 잠겼는지 확인한다.
뮤텍스 구조체에서 가장 중요한 정보이다.
- struct list_head wait_list
뮤텍스를 기다리는 프로세스의 정보를 나타낸다.
이미 다른 프로세스가 뮤텍스를 획득했다고 판단하면 프로세스는 mutex 구조체의 wait_list 주소를 wait_list에 등록한 후 휴면 상태로 진입한다. 뮤텍스를 디버깅할 때 맨 먼저 점검해야 할 필드이다. wait_list에 등록된 연결 리스트 주소가 보이면 뮤텍스를 획득하지 못하고 잠들어서 휴면 상태에 진입한 프로세스가 있다고 볼 수 있다.
뮤텍스를 표현하는 mutex 구조체 외에도 뮤텍스를 기다리는 프로세스를 표현하는 mutex_waiter 구조체가 있다.
mutex_waiter 구조체의 주요 필드를 살펴보자.
-struct list_head list
뮤텍스 획득을 시도하다 잠든 프로세스의 연결 리스트이다. mutex 구조체의 wait_list 필드가 list 필드의 주소를 저장한다.
- struct task_struct *task
뮤텍스를 기다리는 프로세스의 태스크 디스크립터 주소를 저장한다. 뮤텍스를 기다리는 프로세스의 태스크 디스크립터 주소이다. 뮤텍스를 어느 프로세스가 획득했는지 알 수 있는 핵심 자료구조이다.뮤텍스에서 fastpath와 slowpath 동작
뮤텍스 실행 흐름은 fastpath와 slowpath 루틴으로 분류할 수 있다. 각 동작의 의미를 살펴보자.
- fastpath
뮤텍스는 다른 프로세스가 이미 획득하지 않은 상태면 바로 획득할 수 있다. 이 경우 fastpath로 빨리 뮤텍스를 획득하고 해제한다.
- slowpath
fastpath 흐름으로 뮤텍스 획득을 시도했는데 다른 프로세스가 이미 뮤텍스를 획득한 경우 실행되는 동작이다.
slowpath 동작은 크게 다음과 같이 나눌 수 있다.
1. 뮤텍스를 획득하지 못한 프로세스는 대기열에 자신을 등록하고 휴면 상태에 들어감
2. 뮤텍스를 해제한 프로세스는 뮤텍스 대기열에 등록(뮤텍스 획득을 이미 시도)한 다른 프로세스를 깨움
반응형