优先级和时间片是线程的两个重要参数,分别描述线程竞争处理器资源的能力和持有处理器时间长短的能力。
RT-Thread支持256个优先级。数值越小,优先级越高。0为最高优先级,最低优先级预留给空闲线程。用户可以通过rt_config.h中的RT_THREAD_PRIORITY_MAX宏来修改最大支持的优先级。针对STM32默认设置最大支持32个优先级。
具体应用中,线程总数不受限制,可以创建多个优先级相同的线程。能创建的线程总数只和具体硬件平台的内存有关。
时间片只在相同优先级的就绪态线程中起作用,系统对相同优先级的就绪态线程采用时间片轮转的调度方式进行调度。时间片起到约束线程单次运行时长的作用,其单位是一个系统节拍(OS Tick)。
假设有2个相同优先级的就绪态线程A和B,A线程的时间片设置为10,B线程的时间片设置为5,那么,当系统中不存在高于A线程优先级的就绪态线程时,系统会在A、B线程间来回切换执行,并且每次对A线程执行10个节拍的时长,对B执行5个节拍的时长。
操作系统总是让具有最高优先级的就绪任务有限运行:当有任务的优先级高于当前任务的优先级并且处于就绪态后,就一定会发生系统调度。
通过优先级抢占机制,最大限度地满足了系统的实时性。
当操作系统中存在优先级相同的线程时(优先级相同就不会发生抢占),操作系统会按照线程设置的时间片大小轮流调度线程,时间片起到约束线程单次执行时长的作用,其单位是1个系统节拍(OS Tick)。
时间片轮询调度机制,保证优先级相同的线程轮流占用处理器。
timeslice_sample.c
1 #include <rtthread.h> 2 3 #define THREAD_STACK_SIZE 1024 4 #define THREAD_PRIORITY 20 5 #define THREAD_TIMESLICE 10 6 7 /* 线程入口 */ 8 static void thread_entry(void* parameter) 9 { 10 rt_uint32_t value; 11 rt_uint32_t count = 0; 12 13 value = (rt_uint32_t)parameter; 14 while (1) 15 { 16 if(0 == (count % 5)) 17 { 18 rt_kprintf("thread %d is running ,thread %d count = %d\n", value , value , count); 19 20 if(count > 200) 21 return; 22 } 23 count++; 24 } 25 } 26 27 int timeslice_sample(void) 28 { 29 rt_thread_t tid; 30 /* 创建线程1 */ 31 tid = rt_thread_create("thread1", 32 thread_entry, (void*)1, 33 THREAD_STACK_SIZE, 34 THREAD_PRIORITY, THREAD_TIMESLICE); 35 if (tid != RT_NULL) 36 rt_thread_startup(tid); 37 38 39 /* 创建线程2 */ 40 tid = rt_thread_create("thread2", 41 thread_entry, (void*)2, 42 THREAD_STACK_SIZE, 43 THREAD_PRIORITY, THREAD_TIMESLICE-5); 44 if (tid != RT_NULL) 45 rt_thread_startup(tid); 46 return 0; 47 } 48 49 /* 导出到 msh 命令列表中 */ 50 MSH_CMD_EXPORT(timeslice_sample, timeslice sample);
示例中创建了2个动态线程,在线程创建函数的后两个参数分别是线程的优先级和时间片。示例中两个线程的优先级参数是相同的,时间片参数是不同的。
两个线程使用了同一个入口代码。
线程代码中,将线程传入的参数保存在变量中,并计数。然后打印线程参数和计数值。
代码是循环执行的形式,但是是顺序执行的,因为循环内部有循环跳出。
原文:https://www.cnblogs.com/doitjust/p/13295335.html