Automotive Software

쓰레드 스케줄링 (Thread Scheduling) 본문

포직스 (POSIX)/쓰레드 프로그래밍 고급 (Advanced Threaded Program)

쓰레드 스케줄링 (Thread Scheduling)

AutoSW 2020. 10. 25. 23:58

쓰레드도 프로세스와 같이 스케줄링 정책 및 우선순위를 적용하여 스케줄링을 제어할 수 있다. 쓰레드 생성 시 별도로 해당 속성을 설정해 주지 않으면 시스템에서 정의한 방식에 따라 쓰레드의 스케줄링을 처리하게 된다.

예, QNX의 경우, 기본적으로 부모 쓰레드의 스케줄링 정책 및 우선순위를 상속받아 생성된다.

스케줄링 방식을 정의할 때 중요한 것은

  • 스케줄링 정책
    • SCHED_FIFO : First In First Out, 먼저 준비가 된 (Ready Queue에 등록된) 쓰레드를 실행 후 종료 시까지(또는 상위 우선순위를 가진 쓰레드가 준비되기 까지) CPU 점유
    • SCHED_RR : Round Robin, 운영체제에서 정의된 시할당량(Time slice, 예, QNX 4ms)만큼 실행 후 같은 우선순위의 쓰레드들 중 준비가 된 쓰레드에 CPU 를 할당하나 상위 우선 순위의 쓰레드가 준비되면 FIFO와 같이 선점됨
    • SCHED_OTHER : 운영체제에 따라 정의하는 기본 정책이 상이함
  • 쓰레드 우선순위
    • 상기 스케줄링 정책에 우선할 수 있는 것으로 높은 우선순위를 가진 쓰레드가 하위 우선순위의 쓰레드를 선점하여 CPU를 할당받음
      • RR의 경우, 동일한 우선순위(동일 우선순위 Ready Queue내 쓰레드간)를 가진 쓰레드들 사이에서 유효한 스케줄링으로 정의된 시할당량 만료 시 문맥전환이 이루어짐
    • 적용 우선순위의 범위는 운영체제에 따라 상이할 수 있으며 경우에 따라(QNX의 경우) 높은 우선 순위값이 높은 우선순위를 나타내기도 하며 반대의 경우도 있음(예전의 리눅스)

쓰레드에 스케줄링 정책을 적용하기 위해서는

  1. 우선 쓰레드 속성을 하나 만들어 초기화하고 : pthread_attr_init()
  2. 필요시, 현재 부모 쓰레드의 스케줄링값을 읽어오고 : pthread_attr_getschedparam()
  3. 원하는 스케줄링 값으로 변경한 후 해당 값을 속성으로 설정하고 : pthread_attr_setschedparam()
  4. 해당 쓰레드의 스케줄링 정책은 명시적으로 선언함(종속받지 않고)을 알려준다. : pthread_attr_inherisched(, PTHREAD_EXPLICIT_SCHED);

 

int set_ThreadSched(void)
{
  pthread_t threadId;
  pthread_attr_t threadAttr;
  struct sched_param threadSchedParam;
  int status;

  status = pthread_attr_init(&threadAttr);
  if(status != 0)
  {
    return 1;
  }
  else
  {    
    /* set a thread as detached, just an optional setting */
    status = pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
    if(status != 0)
    {
      return 1;
    }
    else
    {
      /* get the priority of main thread */
      status = pthread_attr_getschedparam(&threadAttr, &threadSchedParam);
      if(status != 0)
      {
        return 1;
      }
      else
      {
        /* control the required priority */
        threadSchedParam.sched_priority -= 1; /* lower than main thread */
        
        /* set the priority of thread */
        status = pthread_attr_setschedparam(&threadAttr, &threadSchedParam);
        if(status != 0)
        {
          return 1;
        }
        else
        {
          /* set the attribute for scheduling */
          status = pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED);
          if(status != 0)
          {
            return 1;
          }
          else
          {
            /* create a thread using the attribute */
            pthread_create(&threadId, &threadAttr, ThreadFunc, null);
            return 0;
          }
        }
      }
    }
  }
  return 1;
}