Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

229224
1178
109351


[라즈베리파이] 스케줄링: 프로세스 상태 변화 관리 10. Process Scheduling

프로세스 상태 변화
프로세스 상태 변화에 대해 알아보겠습니다. 프로세스 상태를 아는 것 보다 프로세스 상태가 변경될 때 세부 동작을 이해하는 것이 더 중요합니다.
 

[1] 실행 대기 -> CPU실행 중
프로세스가 생성된 다음 바로 TASK_RUNNING(실행 대기) 상태로 바뀌면서 자신을 런큐에 Enqueue 합니다. 스케줄러가 RUNNING_TASK(실행 대기) 프로세스 중에서 우선 순위가 가장 높은 프로세스를 선택한 다음 CPU에서 실행시킵니다.

프로세스가 CPU를 점유하면서 실행하기 위해서 먼저 TASK_RUNNING 상태로 변경해야 합니다. 실행 후보 프로세스 리스트가 되는 것입니다. 스케줄러에 의해 선택되기 위해 런큐에 Enqueue된 다음 실행 대기 상태를 관리하는 연결 리스트에 등록하는 것입니다.

여기서 한 가지 생각을 해봅시다. 프로세스가 생성된 다음 스스로 자신을 실행할 수 있을까요?
프로세스는 스스로 자신이 실행하고 싶을 때 실행할 수 없습니다. 프로세스는 스케줄러에 의해 실행을 당하는 것입니다. 달리 말하면 스케줄러가 프로세스를 실행하는 것입니다.

스케줄러가 런큐에 있는 실행 대기 목록에 있는 프로세스 중 우선순위가 가장 높은 프로세스를 선택하고 난 다음 CPU로 데리고 갑니다. 기존에 CPU에서 실행 중인 프로세스를 CPU에서 비우고 선택한 프로세스를 CPU에서 실행시킵니다.

CPU 레지스터 세트에서는 새롭게 실행할 프로세스 실행 정보(프로그램 카운터, 스택, 입력 인자) 등등으로 채워지게 됩니다. 스케줄러 현재 CPU를 점유하면서 실행 중인 프로세스보다 우선 순위가 높은 프로세스를 실행하려고 판단을 내립니다. 이 때 CPU를 점유하면서 실행 중인 프로세스를 CPU에서 비우고 새로운 프로세스를 CPU에 채워 줍니다. 이 때 프로세스는 current 프로세스라고 부릅니다.

[2] CPU 실행(TASK_RUNNING) -> 휴면(TASK_INTERRUPTIBLE)
보통 프로세스는 이 흐름으로 휴면에 진입합니다. 프로세스가 다시 깨어나길 기다리거나 지정된 시간 동안 기다리는 상태입니다.

프로세스가 다시 깨어날 조건이 되면 프로세스는 다시 TASK_RUNNING(실행 대기) 상태로 변경하면서 런큐에 Enqueue를 합니다. TASK_RUNNING(실행 대기) 상태로 설정된 프로세스는 스케줄러에 의해 선택되면 CPU에서 실행할 수 있습니다.

[3] CPU 실행 중(TASK_RUNNING) -> 휴면(TASK_UNINTERRUPTIBLE)
프로세스가 특정 조건에서 깨어나 실행하고 싶을 때 TASK_UNINTERRUPTIBLE 상태로 변경합니다. 대부분 프로세스는 다음과 같은 순서로 동작합니다.
+ 자신이 깨어날 조건을 설정
+ TASK_UNINTERRUPTIBLE 상태로 변경
+ schedule() 함수 호출로 휴면에 진입

스케줄링 관점으로 분석하면 명시적 스케줄링 혹은 비선점형 스케줄링 동작이 일어나는 상황이라고 볼 수 있습니다.

이번에 프로세스 동작 관점으로 TASK_UNINTERRUPTIBLE 상태 변경을 바라보면 프로세스가 데이터 입출력과 관련된 I/O 실행 중이거나 프로세스가 뮤덱스를 획득하지 못했을 때 진입하는 상태입니다.

I/O 실행
+ 프로세스가 I/O 관련 동작을 수행 중일 때 CPU를 쓸 필요가 없기 때문에 다른 프로세스가 CPU를 점유할 수 있도록 스스로 TASK_UNINTERRUPTIBLE 상태로 변경합니다. I/O 동작이 끝나면 다시 TASK_RUNNING(실행 대기) 상태로 변경한 후 다시 실행을 재개합니다.

뮤텍스 획득을 못했을 때
+ 프로세스가 뮤텍스를 획득하지 못했을 때 자신을 TASK_UNINTERRUPTIBLE 상태로 바꾼 다음에 휴면에 진입합니다.

[4] 휴면(TASK_INTERRUPTIBLE) -> 실행 대기(TASK_RUNNING)
wake_up_process() 함수를 호출해서 프로세스를 깨울 때 TASK_INTERRUPTIBLE 에서 TASK_RUNNING(실행 대기) 상태로 변경합니다.

[5] 휴면(TASK_UNINTERRUPTIBLE) -> 실행 대기(TASK_RUNNING)
특정 조건에서 프로세스가 깨어난 후 변경하는 상태입니다. 깨어난 프로세스는 다시 실행 대기(TASK_RUNNING) 상태로 변경됩니다.

프로세스 동작 관점에서 다음 상황에서 TASK_UNINTERRUPTIBLE 상태에서 실행 대기(TASK_RUNNING) 상태로 변경됩니다.
+ I/O 실행 완료
+ 뮤텍스를 해제한 프로세스가 뮤텍스 획득을 위해 휴면에 진입한 프로세스를 깨울 때


"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)

Reference(프로세스 스케줄링)

스케줄링 소개
프로세스 상태 관리
   어떤 함수가 프로세스 상태를 바꿀까?
스케줄러 클래스
런큐
CFS 스케줄러
   CFS 관련 세부 함수 분석  
선점 스케줄링(Preemptive Scheduling)   
프로세스는 어떻게 깨울까?
스케줄링 핵심 schedule() 함수 분석
컨택스트 스위칭
스케줄링 디버깅
   스케줄링 프로파일링
     CPU에 부하를 주는 테스트   
     CPU에 부하를 주지 않는 테스트 

핑백

덧글

댓글 입력 영역