rtthread 線程同步量之間的調度

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章