RT-Thread内核实现(六):时间片

整体思想
  • 假如A、B两个线程优先级相同,A先启动,只要A不主动让出CPU,线程B就没机会执行。
  • 时间片就是为了解决相同优先级下多线程的并发问题。
线程控制块
  • 添加rt_ubase_t init_tick属性,remaining_tick记录剩余的时间片。
struct rt_thread
{
    /* rt 对象 */
    char        name[RT_NAME_MAX];    /* 对象的名字 */
    rt_uint8_t  type;                 /* 对象类型 */
    rt_uint8_t  flags;                /* 对象的状态 */
    rt_list_t   list;                 /* 对象的列表节点 */
    
    rt_list_t   tlist;            /* 线程链表节点 */
    
	void        *sp;	          /* 线程栈指针 */
	void        *entry;	          /* 线程入口地址 */
	void        *parameter;	      /* 线程形参 */	
	void        *stack_addr;      /* 线程起始地址 */
	rt_uint32_t stack_size;       /* 线程栈大小,单位为字节 */
    
    rt_ubase_t  init_tick;          /* 初始时间片 */
    rt_ubase_t  remaining_tick;     /* 剩余时间片 */
    
    rt_uint8_t current_priority;    /* 当前优先级 */
    rt_uint8_t init_priority;       /* 初始优先级 */
    rt_uint32_t number_mask;        /* 当前优先级掩码 */
    
    rt_err_t    error;              /* 错误码 */
    
    rt_uint8_t stat;                /* 线程的状态 */
    
    struct rt_timer thread_timer;   /* 内置的线程定时器 */
};
typedef struct rt_thread *rt_thread_t;
线程初始化函数修改
/* 初始化线程 */
    rt_thread_init( &rt_flag1_thread,                   /* 线程控制块 */
                    "rt_flag1_thread",                  /* 线程名字,字符串形式 */
                    flag1_thread_entry,                 /* 线程入口地址 */    
                    RT_NULL,                            /* 线程形参 */
                    &rt_flag1_thread_stack[0],          /* 线程栈起始地址 */    
                    sizeof(rt_flag1_thread_stack),      /* 线程栈大小 */
                    2,                                  /* 线程优先级 */
                    4);                                 /* 时间片 */
时基更新函数修改
  • 如果时间片到了就重置时间片,调用rt_thread_yield()让出CPU。
void rt_tick_increase(void)
{
    struct rt_thread *thread;
    rt_tick ++;
    
    thread = rt_thread_self();
    --thread->remaining_tick;
    
    if(thread->remaining_tick == 0){
        /* 重置时间片 */
        thread->remaining_tick = thread->init_tick;
        
        /* 让出CPU */
        rt_thread_yield();
    }
    
    /* 扫描系统定时器列表 */
	rt_timer_check();
}
  • 函数rt_err_t rt_thread_yield(void)
/**
 * 该函数将让当前线程让出处理器,调度器选择最高优先级的线程运行。当前让出处理器之后,
 * 当前线程还是在就绪态。
 *
 * @return RT_EOK
 */
rt_err_t rt_thread_yield(void)
{
    register rt_base_t level;
    struct rt_thread *thread;

    /* 关中断 */
    level = rt_hw_interrupt_disable();

    /* 获取当前线程的线程控制块 */
    thread = rt_current_thread;
    
    /* 如果线程在就绪态,且同一个优先级下不止一个线程 */
    if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY &&
        thread->tlist.next != thread->tlist.prev)
    {
        /* 将时间片耗完的线程从就绪列表移除 */
        rt_list_remove(&(thread->tlist));
        
        /* 将线程插入到该优先级下的链表的尾部 */
        rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),
                              &(thread->tlist));

        /* 开中断 */
        rt_hw_interrupt_enable(level);

        /* 执行调度 */
        rt_schedule();

        return RT_EOK;
    }

    /* 开中断 */
    rt_hw_interrupt_enable(level);

    return RT_EOK;
}
工程代码

12_time_slice

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2023-06-06 18:10:33,041 INFO sqoop.Sqoop: Running Sqoop version: 1.4.7 2023-06-06 18:10:33,075 WARN tool.BaseSqoopTool: Setting your password on the command-line is insecure. Consider using -P instead. 2023-06-06 18:10:33,218 INFO manager.MySQLManager: Preparing to use a MySQL streaming resultset. 2023-06-06 18:10:33,218 INFO tool.CodeGenTool: Beginning code generation Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. 2023-06-06 18:10:33,782 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM `user_log` AS t LIMIT 1 2023-06-06 18:10:33,825 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM `user_log` AS t LIMIT 1 2023-06-06 18:10:33,834 INFO orm.CompilationManager: HADOOP_MAPRED_HOME is /opt/module/hadoop-3.1.4 注: /tmp/sqoop-root/compile/5f4cfb16d119de74d33f1a0d776d5ae0/user_log.java使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 2023-06-06 18:10:35,111 INFO orm.CompilationManager: Writing jar file: /tmp/sqoop-root/compile/5f4cfb16d119de74d33f1a0d776d5ae0/user_log.jar 2023-06-06 18:10:35,125 WARN manager.MySQLManager: It looks like you are importing from mysql. 2023-06-06 18:10:35,126 WARN manager.MySQLManager: This transfer can be faster! Use the --direct 2023-06-06 18:10:35,126 WARN manager.MySQLManager: option to exercise a MySQL-specific fast path. 2023-06-06 18:10:35,126 INFO manager.MySQLManager: Setting zero DATETIME behavior to convertToNull (mysql) 2023-06-06 18:10:35,130 ERROR tool.ImportTool: Import failed: No primary key could be found for table user_log. Please specify one with --split-by or perform a sequential import with '-m 1'.
06-07

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值