이것이 점프 투 공작소

선점과 프로세스잠금에 대해서 알아보자 본문

리눅스

선점과 프로세스잠금에 대해서 알아보자

겅겅겅 2023. 3. 21. 22:15

선점이란?

스케줄러에서 실행중인 프로세스의 상태를 모니터링하다 더 높은 우선순위의 프로세스가 실행되어야 할 때 현재 실행중인 프로세스를 중단시키는 행위를 말합니다.

운영체제에서 선점은 성능을 향상시키는데 큰 역할을 합니다.

선점이 동작하는 시점

선점되기 위해서는 기본적으로 스케줄러가 호출되어야 하기에 스케줄러가 호출되는 시점과 유사하며

따라서 스케줄러에 현재 실행중인 프로세스보다 높은 우선순위에 스케줄러가 없다면 선점이 일어나지 않습니다.

1. 인터럽트 발생 시

인터럽트가 발생하면 인터럽트 핸들러가 스케줄러를 호출하여 선점이 일어날 수 있습니다.

2. 시스템 콜 발생 시

시스템 콜이 호출되어 커널모드로 전환 될 때 다른 프로세스가 실행 될 수 있도록 스케줄러가 호출됩니다.

3. 타이머 인터럽트 발생 시

운영체제에서 프로세스의 시간 할당량을 제한하기 위해 동작하는 기능입니다.

타이머 인터럽트가 발생하면 스케줄러를 호출합니다.

보통 1ms ~ 10ms 짧은 주기로 발생합니다.

4. 대기 상태의 프로세스가 일어날 때

대기큐에 존재하는 프로세스가 일어나 실행가능한 상태가 되면 스케줄러를 호출합니다.

 

선점과 공유자원

공유자원이란 보통 시스템의 자원 즉 메모리, 네트워크, 파일 등 여러 프로세스가 공유하는 자원을 말합니다.

이런 공유자원에 프로세스들이 동시에 접근하게 된다면 문제가 발생하기 쉽습니다.

간단한 예로 동일한 파일에 여러 프로세스가 동시에 수정작업을 한다면 파일의 일관성이 사라지게됩니다.

따라서 커널은 프로세스의 잠금, 세마포어, 뮤택스, 조건변수 를 이용하여 여러 프로세스가 동시에 공유자원에 대해 접근하는것을 막습니다.

본 포스팅에서는 프로세스의 잠금에 대해서 알아보려고합니다.

 

프로세스 잠금 

프로세스가 공유자원을 점유하고 있지 않을때만 커널은 선점작업을 진행합니다.

각 프로세스의 task_struct 구조체에는 선점가능여부를 카운트하기 위한 값으로 preempt_count라는 변수가 존재합니다.

프로세스가 자원을 획득 할 때 마다 preempt_count변수가 1씩 증가하고 잠금을 해제 할 때마다 1씩 감소합니다.

즉 preempt_count가 0이면 현재 진행중인 작업에 대해서 선점 가능하다고 판단하게됩니다.

preempt_count 변수는 커널 내부에서 task를 생성하거나 스케줄링시마다 초기화되며 인터럽트 처리시에도 값을 증가시켜 인터럽트 처리 또한 중첩되지 않도록 보호하는 기능도 존재합니다.

 

# preempt_count를 증가시키는 함수
void preempt_disable(void)
{
    local_irq_disable(); # 현재 CPU의 인터럽트를 비활성화 합니다.
    current_thread_info()->preempt_count++;
}

# preempt_count를 감소시키는 함수
void preempt_enable(void)
{
    if (--current_thread_info()->preempt_count == 0) 
    # 스레드 정보를 가져오고 preempt_count가 0이면 CPU의 인터럽트를 활성화합니다.
        local_irq_enable();
}