RTT Nano学习笔记 5 - 线程调度

本文详细探讨了实时操作系统RT-Thread中的线程调度算法,包括优先级调度、时间片轮转和主动进程切换。在优先级调度中,高优先级线程会抢占低优先级线程。时间片调度确保了相同优先级的线程公平分享CPU资源。通过进程睡眠和主动放弃CPU控制权,线程可以在适当时候让出执行权。实验展示了不同调度策略下线程执行的顺序和频率,揭示了时间片分配对调度的影响。
摘要由CSDN通过智能技术生成

目录

1.优先级调度

2. 时间片调度

3. 主动切换

3.1 进程睡眠

3.2 放弃进程


RT-Thread的线程调度算法是基于优先级的全抢占式多线程调度算法,即在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的,包括线程调度器自身。

通过2个进程了解调度

static void thread1Entry(void *parameter)
{
    uint32_t count = 0;

    while (1)
    {
        Printf("1:%d\n", count++);
        delayms(600);
    }
}

static void thread2Entry(void *parameter)
{
    uint32_t count = 0;

    while (1)
    {
        Printf("2:%d\n", count++);
        delayms(300);
    }
}

为了减少打印信息,加入delayms函数延时(通过for循环延时)。

1.优先级调度

将2个进程创建为不同的优先级,进程1的优先级高于进程2。

    rtosCreateThread(
        handle1, 
        "thread1",
        thread1Entry, 
        (void *)0,
        NULL,
        256,
        RT_THREAD_PRIORITY_MAX - 2, 
        10);
        
    if(handle1 != NULL)
        Printf("Create Thread 1 OK\n");
        
    rtosCreateThread(
        handle2, 
        "thread2",
        thread2Entry, 
        (void *)0,
        NULL,
        256,
        RT_THREAD_PRIORITY_MAX - 1, 
        10);

    if(handle2 != NULL)
        Printf("Create Thread 2 OK\n");
        
    rtosStartThread(handle1);
    rtosStartThread(handle2);

从打印结果看,进程1一直在运行,进程2则没有运行过。

如果把2个进程的优先级设置为一样的(注意2个进程的时间片大小设置成一样的)。由于进程1延时时间是进程2的一倍,所以看到的打印结果是:

1:0
2:0
2:1
1:1
2:2
2:3
1:2
2:4
2:5

这里碰到一个问题,程序运行一段时间后,进程2就独占CPU了,进程1不再运行,GD32F450会很快发现这个问题,而STM32则需要很久才会发生。

2. 时间片调度

相同优先级线程按照时间片轮番调度。

将上面例子中2个进程的时间片修改为300,600.

1:0
2:0
2:1
2:2
1:1
2:3
2:4
2:5
2:6
2:7

进程1分配了300ms,延时600ms,所以开始运行了一次后交出控制权,进程2分配了600ms,延时300ms,所以这里会打印多次‘2’(delayms并不是很准导致不是2次)。

从这可以看出去,分配时间片长的相当于优先级更高。

3. 主动切换

进程可以主动交出CPU控制权,最常见的方法是进程睡眠。

3.1 进程睡眠

将上例中的2个进程设置为不同优先级(同章节1),然后把进程1的delayms改为RTOS的睡眠函数rtosThreadSleep。

static void thread1Entry(void *parameter)
{
    uint32_t count = 0;

    while (1)
    {
        Printf("1:%d\n", count++);
        rtosThreadSleep(600 * RTOS_TICK_PER_SECOND / 1000);
    }
}

打印结果:

1:0
2:0
2:1
2:2
1:1
2:3
2:4
1:2
2:5
2:6
2:7

进程1先运行1次,睡眠后交出控制权,进程2开始运行,因为此时进程1是睡眠600ms,进程1的优先级比进程2高,所以进程2一直运行直到进程1的睡眠时间到,马上就拿到控制权。

3.2 放弃进程

通过rt_thread_yield放弃进程应该仅对优先级相同时有效,在上面3.1的例子上将rtosThreadSleep改为rt_thread_yield();

测试发现一直运行进程1。这是因为进程在执行完rt_thread_yield后进入就绪状态,但是进程1的优先级比进程2高,所以还是执行进程1。

将进程1的优先级改为和进程2一样,并且将时间片改为1200,而进程2的时间片仍然为600

    rtosCreateThread(
        handle1, 
        "thread1",
        thread1Entry, 
        (void *)0,
        NULL,
        256,
        RT_THREAD_PRIORITY_MAX - 1, 
        1200);

打印结果:

1:0
2:0
2:1
2:2
1:1
2:3
2:4
1:2
2:5
2:6
2:7

尽管进程1分配了2倍的时间片,但是运行yield后直接交出了控制权,进程2运行分配的600ms时间片后进程1再执行一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值