회사 업무를 하면서 짬짬히 리눅스 공부를 하고 있습니다.
Process Management 공부를 시작 했는데 시작부터 난관이군요. ㅋ
리눅스 스케줄러 정책으로
SCHED_NORMAL (2.4에서는 SCHED_OTHER)
SCHED_FIFO
SCHED_RR
이 있는 것으로 알고 있습니다. SCHED_FIFO, SCHED_RR은 실시간 프로세스
스케줄링에 사용 한다고 되어 있는데 SCHED_NORMAL 하고의 차이점이 어떻게 되는지 모르겠네요.
SCHED_NORMAL도 기본적으로 priority round robin을 하는 것으로 알고 있습니다.
혹자는 SCHED_NORMAL은 preemption이 안된다는 얘기를 하기도 하구요.
차이점을 조금이나마 알고 계신 분 한수 부탁 드립니다. ^^;
댓글 9
-
김연희
2011.02.23 15:57
-
이정승
2011.02.23 17:25
음. 위에서 잘 설명주셨는데요.
관점에 따라서 리눅스 커널 내부와는 약간 다른 부분이 있어 첨언 드립니다.
일단 userlevel에서의 posix API 기준으로 설명을 주신것 같은데요.
linux 커널에서 살펴보면 각 policy 별로 가질 수 있는 priority는 다음과 같습니다.
(낮은 숫자가 높은 우선순위)
SCHED_FIFO (RT) : 0 ~ 99
SCHED_RR (RT) : 0 ~ 99
SCHED_NORMAL : 100 ~ 139
100을 기준으로 100 미만은 RT task, 100 이상은 일반 task로 구분됩니다.
RT task의 특징은
말씀주신대로 우선순위가 가장 높은 task는 다른 task 를 '항상' 선점한다 입니다.
커널 내부 기준으로 표를 다시 그리면 아래와 같이 될 것 같은데요.^^;
priority threads
--------------------------------------------------------------
120 a(sched_normal)
--------------------------------------------------------------
99 b(sched_rr) c(sched_rr) d(sched_fifo)
98
.
.
.
0 e(sched_fifo)
--------------------------------------------------------------
e라는 task는 다른 task를 항상 선점하게 됩니다.
RT task에서 yield()의 역할은 task를 우선순위 별로 있는 실행리스트의 끝부분에 넣는 역할을 하기 때문에
e라는 task에서 yield()가 호출되어도 e는 선점당하지 않습니다.
wait queue로 이동하게되는 sleep(), I/O 작업 수행시 block 되는 경우는e라는 task가 runqueue 에 존재하지 않기 때문에 e는 선점되고 당연히 b,c,d 순으로 수행되게 됩니다.
추가로 SCHED_NORMAL은 round-robin 이 아닌 우선순위기반 스케쥴링인 O(1)이나 CFS스케쥴러(2.6.23 이상)에 의해
스케쥴링 됩니다.
커널을 훑어보니 SCHED_BATCH 나 SCHED_IDLE 속성이 추가로 생겼더군요.
일반 task와 거의 유사하나 batch task , cpu time이 거의 필요없는 task에 유용한 속성으로 생각되네요.
-
홍문화
2011.02.23 18:36
와~ 이렇게 자세히 답변을 달아주실 줄이야. ^^;
두분 모두 감사합니다.
RT task는 yield()에 의해 wait queue로 가지 않고 같은 우선순위의 실행리스트 끝으로 이동 하는군요.
RT task가 아닌 경우에는 priority가 높아도 선점을 할 수 없나요?
b, c가 time quantum을 소진하면 d가 실행 된다고 하셨는데 만일 e에 의해 선점 당하지 않거나 스스로 block, yield(), sleep() 하지 않는 경우에는 실행 시간을 모두 소비 할때까지 동작하게 되는 것인가요?
그리고 일반적으로 임베디드 시스템에서는 기본 스케줄링 정책을 SCHED_NORMAL로 사용하고 원하는 쓰레드들에 대해서만 SCHED_FIFO, SCHED_RR 속성을 주는 방식을 사용 하나요? 아니면 기본 스케쥴링 정책을 SCHED_RR과 같은
실시간으로 설정 하고 priority만 조정해서 사용 하나요?
공부를 하면 할수록 해야 될 것이 점점 많아지는것 같습니다. ^^;
-
백창우
2011.04.12 03:41
비디오 스트림 처리나 특수한 사운드 처리라면 납득이 가는군요.
저도 codec쪽에 다소 황당했던 최적화 경험을 하나 가지고 있습니다.
-
이정승
2011.04.12 03:08
>임베디드환경에서는 RT가 자주사용 되는 편이지만
>일반적인 상황에서 다른 task의 응답성을 마구 저해하는 (-_-) RT task를 만들 이유는 별로 없습니다.
문맥을 읽고 답글을 다셨다면 아시겠지만 일반적으로 RT task를 사용하지 않으나
서버군이나 desktop에 비해서 임베디드 시스템에서는 RT가 자주사용되는 편이라는 말씀을 드린겁니다.
아실지는 모르겠지만 적지 않은 CE device에서 RT task가 사용됩니다.
특히 제가 개발하는 환경(매우 특수한 임베디드 시스템 환경이 아닌) 에서는
비디오스트림 처리나 사운드처리에 주로 사용되는데
당연히 사용성을 저해하는 요소가 되기 때문에 골머리중입니다.
아.. 왜 비디오 스트림 처리에 RT task까지 필요하나라는 질문(?)에 대비해서 미리 말씀을 드리자면
세상에는 흔히 저희들이 바온 스트림만 존재하는게 아니더군요..
-
백창우
2011.04.12 02:42
임베디드 환경에서 Real-Time scheduling이 자주 사용된다라...
전혀 그렇지 않습니다.
매우 특수한 임베디드 시스템 환경이 아니고서는 아예 사용되지 않죠.
만약 Real-time scheduling을 사용해야되는 매우 특수한 임베디드 시스템이라면,
리눅스를 사용하지 않고 아예 RTOS 계열 OS를 사용하죠.
-
이정승
2011.02.23 20:22
밑에서 설명을 주셨던데 못보고 썼던 글이 아까워서........... 댓글 드립니다.
>>RT task는 yield()에 의해 wait queue로 가지 않고 같은 우선순위의 실행리스트 끝으로 이동 하는군요.
근데.. yield() 호출 시 RT 나 NORMAL task 모두 wait queue로 가지는 않습니다.
RT task는 설명드린 내용과 같고
NORMAL task는
O(1) 의 경우는 runqeue 내에 존재하는 active queue -> expire queue 로
CFS의 경우는 runqueu를 구성하고 있는 RB-tree 내에 적당한 위치로 수행하고 있는 current task를 이동하게 됩니다.
좀 복잡해지는데 단순히 current task의 quantum 이 남아 있더라도 수행을 그만두고
다시 스케쥴링이 되는것을 기다린다라고 이해하시면 될 것 같습니다.
>>b, c가 time quantum을 소진하면 d가 실행 된다고 하셨는데 만일 e에 의해 선점 당하지 않거나
>>스스로 block, yield(), sleep() 하지 않는 경우에는 실행 시간을 모두 소비 할때까지 동작하게 되는 것인가요?
b,c는 time quantum을 소비할때까지 동작하게 됩니다.보통 timq quantum은 그리긴 시간이 아닙니다. 길어도 몇백ms 정도..
>>그리고 일반적으로 임베디드 시스템에서는 기본 스케줄링 정책을 SCHED_NORMAL로 사용하고
>>원하는 쓰레드들에 대해서만 SCHED_FIFO, SCHED_RR 속성을 주는 방식을 사용 하나요?
>>아니면 기본 스케쥴링 정책을 SCHED_RR과 같은 실시간으로 설정 하고 priority만 조정해서 사용 하나요?
process (user)를 생성하면 기본적으로 우선순위 120의 SCHED_OTHER 속성으로 task가 생성됩니다.
(부모 task 의 속성을 이어받게 되지만.. sh의 우선순위는 그러하지요)
그 후 필요할때 API를 이용해서 task의 policy를 수정해주게 됩니다.
#> man -k sched 참고
임베디드환경에서는 RT가 자주사용 되는 편이지만
일반적인 상황에서 다른 task의 응답성을 마구 저해하는 (-_-) RT task를 만들 이유는 별로 없습니다.
-
김연희
2011.02.23 19:57
-RT스레드가 아닐 경우에는 O(1),CFS등의 방식에 따라 스케줄링되므로 해당 스케줄링 방식에 따라 확인하시면 될 듯 합니다. 제 생각으로는 RT스레드가 아니면 우선순위에 대한 선점을 고려해서 개발하는 것은 의미가 없어 보입니다. 보장해주지 않으니까요.
-b,c는 SCHED_RR이므로 정해진 실행시간을 다 소비하면 실행리스트 마지막으로 이동합니다.
-스케줄 정책과 우선순위는 스레드를 생성한 후에 설정하면 됩니다.
===================================================================
task_t *_thread;
struct sched_param param;
_thread = (task_t*)kthread_create(thread_func, 0, "hello");
if (_recorder_thread== ERR_PTR(-ENOMEM)) {
printk("fail!n");
}
param.sched_priority = 99;
sched_setscheduler(_thread, SCHED_FIFO, ¶m);
wake_up_process(_thread);
===================================================================위 코드 정도를 참조하시면 될 것 같습니다. -
홍문화
2011.02.23 23:00
김연희님, 이정승님 두분 답변 진심으로 감사 드립니다.
2.4 스케줄러를 시작으로 O(1) 스케줄링 방식 공부 하고 있는데 쉽지가 않네요.
그래서일까요? 요즘들어 대학원을 가고 싶다는 생각이 계속 드는군요. ㅋ
나이 29살에 제대로 재미를 붙이는 바람에... 좀 더 일찍 재미를 붙였으면 대학원 결심을 했을텐데.
올해에는 커널 스터디에 꼭 참석 해야 겠습니다. ^^;
.
고수님들께서 정확한 답변을 달기 전에 한번 올려 봅니다 ㅎㅎㅎ
SCHED_NORMAL스레드는 priority값을 0만 가질 수 있고, time share하면서 동등하게 스케줄됩니다.
SCHED_FIFO스레드는 priority값을 1~99까지 가질 수 있고, sched_yield()호출하거나, runnable한 상태가 되면 priority에 해당하는 대기 리스트의 맨 뒤로 갑니다. 자신보다 더 높은 priority를 가진 스레드에 의해서만 선점되고, 선점한 스레드가 cpu를 놓아주면 계속 동작 합니다. (선점되도 계속 대기리스트 맨 앞자리를 유지)
SCHED_RR스레드는 SCHED_FIFO스레드와 기본적으로 동일하게 동작하되, time quantum을 소진하면 priority의 대기리스트 뒤로 갑니다.
priority threads
--------------------------------------------------------------
0 a(sched_normal)
--------------------------------------------------------------
1 b(sched_rr) c(sched_rr) d(sched_fifo)
2
.
.
.
99 e(sched_fifo)
--------------------------------------------------------------
위처럼 스레드가 있을경우 a는 b,c,d,e에 의해 항상 선점되고,
b,c,d는 e에 의해 선점되지 않으면 실행됩니다. b,c는 일정 시간동안 동작한 후 대기리스트 뒤로 이동합니다. d는 스스로 yield하거나 block되거나 e에 의해 선점되기 전까시 실행됩니다. b가 runnable상태가 되거나, 스스로 sched_yield()호출하면 대기리스트 뒤로 가고, b,c가 다시 실행됩니다.
e는 여기서 항상 동작할 수 있습니다. runnable하면 무조건 선점하지요. e 스레드 안에서 sleep(),yield()나 block등으로 인해 동작하지 않는 남은 시간을 a,b,c,d가 나눠가지면서 동작하게 됩니다.