原创 SylixOS下线程优先级调度

2015-7-31 17:05 1489 18 18 分类: 软件与OS 文集: SylixOS应用开发

SylixOS支持POSIX编程标准,其优先级调度可以使用POSIX的函数直接设置,但测试发现在优先级调度上有稍许不同,SylixOS下的优先级调度策略只支持SCHED_RRSCHED_FIFO两种,不支持SCHED_OTHER。不过作为一个实时系统,如此设计也是理所当然。

SylixOS优先级上需要注意,SylixOS自身定义的API设置优先级时优先级设置值越小则该线程优先级越高。如果使用POSIX定义API,优先级设置值越大其优先级越高。在文件k_priority.h 中说明了SylixOS中优先级设置使用注意事项,这里的优先级针对SylixOS自定义API,在POSIX下用户线程优先级设置范围为5205

/************************************************************************
  优先级 (一般应用的最高优先级不能高于 LW_PRIO_CRITICAL 最低不能低过 LW_PRIO_LOW)
************************************************************************/
#define LW_PRIO_EXTREME    LW_PRIO_HIGHEST  /*  最高优先级            */
#define LW_PRIO_CRITICAL   50               /*  关键处理任           */
#define LW_PRIO_REALTIME   100              /*  实时处理任务         */
#define LW_PRIO_HIGH       150              /*  高优先级任务         */
#define LW_PRIO_NORMAL     200              /*  正常优先级           */
#define LW_PRIO_LOW        250              /*  低优先级             */
#define LW_PRIO_IDLE       LW_PRIO_LOWEST   /*  最低优先级           */

为了对比SylixOS优先级调度的结果,设计2个线程分别验证:

  • SCHED_FIFO调度模式下,相同优先级的调度情况;
  • SCHED_FIFO调度模式下,不同优先级的调度情况;
  • SCHED_RR调度模式下,相同优先级的调度情况;
  • SCHED_RR调度模式下,不同优先级的调度情况;
  • 使用默认设置创建线程,线程的调度情况。

在程序中创建两个线程,分别打印各自的信息,修改不同的调度方式和优先级,程序执行后会有不同的输出,读者根据代码中的提示查看修改即可。

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<sched.h>
#include<unistd.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<string.h>

void *fun_thread(void *arg)
{
   int                id = (int)arg;
   int                i,j;
   int                policy;
   int                priority;
   struct sched_param param;

   printf("thread %d start\n", id);
   sleep(id + id);

   pthread_getschedparam(pthread_self(), &policy, &param);
   /* 分析线程的调度策略
    * SylixOS中SCHED_RR与SCHED_OTHER的定义相同
    */
   if (policy == SCHED_RR) {
       priority = param.sched_priority;
       printf("thread %d SCHED_RR=%d \n", id, priority);
   }

   if (policy == SCHED_FIFO) {
       priority = param.sched_priority;
       printf("thread %d SCHED_FIFO=%d \n", id, priority);
   }

   for (i = 1; i < 10; i++) {
      for(j = 1; j < 100000000; j++) {
      }
      printf("this is thread %d\n", id);
   }
   printf("Thread %d exit\n", id);
   return (NULL);

}

int main(int argc, char *argv[])
{
   int id = 0;
   int i = getuid();    /*  获取当前进程用户名  */
   if (i == 0) {
      printf("The current user is root\n");
   } else {
      printf("The current user is not root\n");
   }

   pthread_t           tid1,tid2;
   pthread_attr_t      attr1,attr2;
   struct sched_param  param1;
   struct sched_param  param2;
   param1.sched_priority = 98;
   param2.sched_priority = 99;

   pthread_attr_init(&attr1);    /*  使用默认设置初始化线程属性  */
   pthread_attr_init(&attr2);

   /* PTHREAD_EXPLICIT_SCHED 新创建线程使用设置属性,
    * PTHREAD_INHERIT_SCHED  新创建线程继承主线程属性
    */
   pthread_attr_setinheritsched(&attr1, PTHREAD_EXPLICIT_SCHED);
   pthread_attr_setinheritsched(&attr2, PTHREAD_EXPLICIT_SCHED);

   /*
    * 设置线程调度策略
    * SCHED_FIFO  若无更高优先级任务打断,该任务运行直至结束
    * SCHED_RR    相同优先级任务会平衡调度,各个任务都能得到执行
    * param1      设置线程优先级,
    */
   pthread_attr_setschedpolicy(&attr1, SCHED_FIFO);
   pthread_attr_setschedparam(&attr1, &param1);

   pthread_attr_setschedpolicy(&attr2, SCHED_FIFO);
   pthread_attr_setschedparam(&attr2, &param2);

   sleep(1);
   /*
    *  创建线程,并设置优先级,
    *  若将 &attr1/2 使用 NULL 替换,标识线程使用默认设置创建
    */
   id++;
   pthread_create(&tid1, &attr1, fun_thread, (void *)id);

   id++;
   pthread_create(&tid2, &attr2, fun_thread, (void *)id);

   pthread_join(tid1, NULL);
   pthread_join(tid2, NULL);

   pthread_attr_destroy(&attr1);
   pthread_attr_destroy(&attr2);

   return (0);

}

需要注意的是,由于线程中使用for循环模拟线程任务,当使用release版本编译时,会将此部分代码进行优化,从而影响实验效果。

文章评论0条评论)

登录后参与讨论
我要评论
0
18
关闭 站长推荐上一条 /2 下一条