실시간 태스크 우선순위란?
실시간 시스템에서 태스크의 우선순위는 시스템의 응답성과 성능에 직접적인 영향을 미친다. 우선순위가 높은 태스크는 우선순위가 낮은 태스크보다 먼저 실행되며, 이는 중요한 실시간 작업이 제 시간에 완료될 수 있도록 보장한다.
리눅스에서의 실시간 우선순위 설정
리눅스는 실시간 스케줄링 정책을 지원하여 우선순위를 설정하고 관리할 수 있다. 실시간 스케줄링 정책에는 SCHED_FIFO
, SCHED_RR
, SCHED_DEADLINE
이 있다.
SCHED_FIFO
SCHED_FIFO
(First In, First Out)는 비선점 스케줄링 정책으로, 가장 높은 우선순위를 가진 태스크가 완료되기 전까지 CPU를 계속 사용한다. SCHED_FIFO
정책에서 우선순위를 설정하려면 sched_setscheduler
함수와 sched_param
구조체를 사용한다.
#include <sched.h>
#include <pthread.h>
void set_real_time_priority(pthread_t thread, int priority) {
struct sched_param param;
param.sched_priority = priority;
if (pthread_setschedparam(thread, SCHED_FIFO, ¶m) != 0) {
perror("pthread_setschedparam");
}
}
위 코드는 주어진 쓰레드에 대해 SCHED_FIFO
스케줄링 정책을 사용하고, 지정된 우선순위를 설정하는 함수다.
SCHED_RR
SCHED_RR
(Round Robin)은 선점형 스케줄링 정책으로, 같은 우선순위를 가진 태스크들이 주기적으로 CPU 사용 시간을 번갈아가며 사용한다. SCHED_RR
역시 sched_setscheduler
와 sched_param
을 사용해 우선순위를 설정할 수 있다.
#include <sched.h>
#include <pthread.h>
void set_rr_priority(pthread_t thread, int priority) {
struct sched_param param;
param.sched_priority = priority;
if (pthread_setschedparam(thread, SCHED_RR, ¶m) != 0) {
perror("pthread_setschedparam");
}
}
SCHED_DEADLINE
SCHED_DEADLINE
은 데드라인을 기반으로 하는 실시간 스케줄링 정책으로, 특정 시간 안에 태스크를 완료해야 하는 시스템에서 사용된다. SCHED_DEADLINE
정책은 리눅스 커널에서 비교적 최근에 추가된 기능으로, 정확한 사용 방법은 커널 문서를 참고해야 한다.
우선순위 범위
리눅스에서 실시간 태스크 우선순위 범위는 일반적으로 1에서 99까지로 설정된다. 높은 숫자가 더 높은 우선순위를 의미하며, 이는 태스크가 더 빨리 처리될 가능성이 높음을 나타낸다.
#define MIN_PRIORITY 1
#define MAX_PRIORITY 99
예제: 실시간 우선순위 설정
다음은 리눅스에서 실시간 우선순위를 설정하는 예제 코드이다. 이 코드는 쓰레드를 생성하고, 생성된 쓰레드에 대해 실시간 우선순위를 설정한다.
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
void* thread_function(void* arg) {
// 실시간 태스크로 수행할 작업
while (1) {
printf("Real-time task running\n");
usleep(100000); // 100ms
}
return NULL;
}
int main() {
pthread_t thread;
struct sched_param param;
// 쓰레드 생성
if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 우선순위 설정
param.sched_priority = 50;
if (pthread_setschedparam(thread, SCHED_FIFO, ¶m) != 0) {
perror("pthread_setschedparam");
exit(EXIT_FAILURE);
}
// 메인 쓰레드 대기
pthread_join(thread, NULL);
return 0;
}
이 예제는 우선순위 50을 가진 SCHED_FIFO
정책을 설정한 실시간 태스크를 생성하고, 해당 태스크가 무한 루프를 돌며 주기적으로 메시지를 출력하도록 한다.
실시간 우선순위 관리의 중요성
실시간 우선순위 관리의 중요성은 다음과 같은 이유로 강조될 수 있다:
- 예측 가능성: 실시간 시스템에서는 특정 작업이 정해진 시간 내에 완료되는 것이 중요하다. 우선순위 관리를 통해 중요한 작업이 필요한 시간에 완료될 수 있도록 보장한다.
- 응답성 향상: 중요한 작업에 높은 우선순위를 부여함으로써 시스템의 응답성을 향상시킬 수 있다. 이는 특히 임베디드 시스템이나 산업용 제어 시스템 등에서 중요하다.
- 자원 최적화: 우선순위 관리는 CPU와 같은 시스템 자원을 효율적으로 사용하도록 도와준다. 높은 우선순위를 가진 작업이 적시에 실행되므로, 자원 낭비를 최소화할 수 있다.
실시간 우선순위 설정 시 고려사항
실시간 우선순위를 설정할 때 몇 가지 중요한 고려사항이 있다:
- 우선순위 역전: 낮은 우선순위 태스크가 높은 우선순위 태스크에 의해 선점되지 않고 실행될 때, 우선순위 역전 현상이 발생할 수 있다. 이를 방지하기 위해 우선순위 상속 프로토콜(priority inheritance protocol)을 사용할 수 있다.
- 데드락 회피: 여러 실시간 태스크가 상호 배제 자원을 사용할 때, 데드락이 발생하지 않도록 주의해야 한다. 올바른 락 순서를 유지하고, 타임아웃 메커니즘을 사용하는 것이 필요하다.
- 적절한 우선순위 할당: 모든 태스크에 대해 적절한 우선순위를 설정하는 것은 매우 중요하다. 우선순위가 너무 높거나 낮으면 시스템의 응답성과 효율성이 저하될 수 있다.
실시간 우선순위의 실세계 적용 사례
실시간 우선순위는 다양한 분야에서 활용된다:
- 자동차 제어 시스템: 자율 주행 자동차에서 실시간 우선순위를 통해 차량의 제어 시스템, 센서 데이터 처리, 통신 등을 관리한다.
- 의료 장비: 실시간 우선순위는 의료 장비에서 생명과 관련된 작업을 적시에 처리하기 위해 사용된다.
- 항공 우주: 항공기 제어 시스템에서 실시간 우선순위는 안전-critical 태스크를 적시에 수행하기 위해 필수적이다.
실시간 우선순위 설정은 실시간 시스템에서 필수적인 요소이다. 리눅스와 같은 운영체제에서 제공하는 실시간 스케줄링 정책을 적절히 활용하여, 시스템의 응답성과 성능을 최적화할 수 있다. 중요한 점은 우선순위 관리에서 발생할 수 있는 문제들을 사전에 인지하고, 적절한 해결 방안을 마련하는 것이다.