线程让出处理器

当前线程的时间片用完或者该线程自动要求让出处理器资源时,它不再占有处理器,调度器会选择相同优先级的下一个线程执行。线程调用这个接口后,这个线程仍然在就绪队列中。线程让出处理器使用下面的函数接口:

  1. rt_err_t rt_thread_yield(void);

调用该函数后,当前线程首先把自己从它所在的就绪优先级线程队列中删除,然后把自己挂到这个优先级队列链表的尾部,然后激活调度器进行线程上下文切换(如果当前优先级只有这一个线程,则这个线程继续执行,不进行上下文切换动作)。

线程安全

安全

中断例程

可调用

函数参数

函数返回

线程让出处理器代码的例子如下示:

  1. /*
  2. * 程序清单:线程让出处理器
  3. * 在这个例子中,将创建两个相同优先级的线程, 它们会通过rt_thread_yield
  4. * 接口把处理器相互让给对方进行执行。
  5. */
  6. #include <rtthread.h>
  7. #include "tc_comm.h"
  8.  
  9. /* 指向线程控制块的指针 */
  10. static rt_thread_t tid1 = RT_NULL;
  11. static rt_thread_t tid2 = RT_NULL;
  12. /* 线程1入口 */
  13. static void thread1_entry(void* parameter)
  14. {
  15. rt_uint32_t count = 0;
  16.  
  17. while (1)
  18. {
  19. /* 打印线程1的输出 */
  20. rt_kprintf("thread1: count = %d\n", count ++);
  21.  
  22. /* 执行yield后应该切换到thread2执行 */
  23. rt_thread_yield();
  24. }
  25. }
  26.  
  27. /* 线程2入口 */
  28. static void thread2_entry(void* parameter)
  29. {
  30. rt_uint32_t count = 0;
  31.  
  32. while (1)
  33. {
  34. /* 打印线程2的输出 */
  35. rt_kprintf("thread2: count = %d\n", count ++);
  36.  
  37. /* 执行yield后应该切换到thread1执行 */
  38. rt_thread_yield();
  39. }
  40. }
  41.  
  42. int rt_application_init(void)
  43. {
  44. /* 创建线程1 */
  45. tid1 = rt_thread_create("thread",
  46. thread1_entry, /* 线程入口是thread1_entry */
  47. RT_NULL, /* 入口参数是RT_NULL */
  48. THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
  49. if (tid1 != RT_NULL)
  50. rt_thread_startup(tid1);
  51.  
  52. /* 创建线程2 */
  53. tid2 = rt_thread_create("thread",
  54. thread2_entry, /* 线程入口是thread2_entry */
  55. RT_NULL, /* 入口参数是RT_NULL */
  56. THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
  57. if (tid2 != RT_NULL)
  58. rt_thread_startup(tid2);
  59.  
  60. return 0;
  61. }
  • 注:rt_thread_yield()函数和rt_schedule()函数比较相像,但在有相同优先级的其他就绪态线程存在时,系统的行为却完全不一样。执行rt_thread_yield()函数后,当前线程被换出,相同优先级的下一个就绪线程将被执行。而执行rt_schedule()函数后,当前线程并不一定被换出,即使被换出,也不会被放到就绪线程链表的尾部,而是在系统中选取就绪的优先级最高的线程执行(如果系统中没有比当前线程优先级更高的线程存在,那么执行完rt_schedule()函数后,系统将继续执行当前线程)。