rtthread 线程同步量之间的调度
#include <rtthread.h>
/*
rt_schedule() // thr1 执行
重新调度线程; 在这个函数中进行调度, 进入调度后的线程中执行, 直到执行到rt_schedule(),
所以一个线程被在调度之前都执行到了rt_schedule()处, 线程再次被调度时, 就会从 rt_schedule() 后继续执行.
rt_sem_take,rt_sem_release等都会触发线程调度(rt_schedule)
sem
take所在优先级 高于 release所在优先级 正常
take所在优先级 等于 release所在优先级 正常
take所在优先级 低于 release所在优先级 异常; take线程从未被调用,即使资源已经被释放
mutex(用在两个线程时, 要两个锁才能实现线程间同步)
take所在优先级 高于 release所在优先级 异常; release线程进入一次, 然后一直是take线程在执行
take所在优先级 等于 release所在优先级 异常;
release线程进入一次, 然后绝大数是take线程在执行, 偶尔release线程执行一次(猜测: 偶尔一次release线程执行, 应该是时间片调度)
take所在优先级 低于 release所在优先级 异常; 一直是release线程在执行
mb
邮箱在中断中,rt_mb_send不会产生调度(rt_schedule),要等中断处理结束之后
"中断中线程切换策略"与"立即进行切换策略"
在中断中释放了一个信号量,唤醒了某线程,但通过判断发现当前系统处于中断上下文环境中,那么在进行线程切换时应该采取中断中线程切换的策略,而不是立即进行切换。
*/
static rt_sem_t sem;
static rt_mutex_t mutex;
static void test1_entry(void *parameter)
{
rt_thread_mdelay(3000);
rt_kprintf("[test1_entry] start\n");
while (1)
{
rt_kprintf("[test1_entry] rt_sem_take 1\n");
//rt_sem_take(sem, RT_WAITING_FOREVER);
rt_mutex_take(mutex, RT_WAITING_FOREVER);
rt_kprintf("[test1_entry] rt_sem_take 2\n");
}
}
static void test2_entry(void *parameter)
{
rt_mutex_take(mutex, RT_WAITING_FOREVER);
rt_thread_mdelay(3000);
while(1){
rt_kprintf("[test2_entry] rt_sem_release 1\n");
//rt_sem_release(sem);
rt_mutex_release(mutex);
for(int i=0; i<10000; i++)
for(int j=0; j<10000; j++);
rt_kprintf("[test2_entry] rt_sem_release 2\n");
for(int i=0; i<10000; i++)
for(int j=0; j<10000; j++);
//rt_thread_mdelay(1000);
}
}
int test_sem_switch(void)
{
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
rt_thread_t thread;
thread = rt_thread_create("test1", test1_entry, RT_NULL, 1024, 16, 10);
if (thread != RT_NULL)
{
rt_thread_startup(thread);
rt_kprintf("rt_thread_startup test1 end\n");
}
else
{
rt_kprintf("create test1 thread failed!\n");
}
thread = rt_thread_create("test2", test2_entry, RT_NULL, 1024, 15, 10);
if (thread != RT_NULL)
{
rt_thread_startup(thread);
rt_kprintf("rt_thread_startup test2 end\n");
}
else
{
rt_kprintf("create test2 thread failed!\n");
}
}
MSH_CMD_EXPORT(test_sem_switch, test_sem_switch);