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);