线程创建

  • python 创建线程提供了较为便捷的创建方式,忽略了底层的栈大小配置,优先级等参数传递,尽量简化用户使用。python 创建线程时会在底层 RTOS 系统中生成对应的任务控制块(TCB),用于任务调度及线程资源控制。
  • 协议栈大小默认配置 8k。并且也为客户提供了栈大小的配置,可以通过 _thread.stack_size() 接口对栈大小进行配置查询。
  1. import _thread
  2. import utime
  3. # 线程函数入口,实现每隔一秒进行一次打印。
  4. def thread_func_entry(id, name):
  5. while True:
  6. print( 'thread {} name is {}.'.format(id, name))
  7. utime.sleep(1)
  8. # 创建线程
  9. _thread.start_new_thread(thread_func_entry, (1, 'QuecPython'))

线程状态

线程有着自己的生命周期,从创建到结束,总是处于下面五个状态之一:新建状态(creation)、就绪状态(runnable)、运行状态(running)、阻塞状态(blocked)、终止状态(dead)。

代码 - 图1

  • 新建状态(creation):创建线程,实现线程可运行状态初始化。
  • 就绪状态(runnable):处于这个状态的线程位于可运行池中,等待获得 CPU 的使用权。
  • 运行状态(running):当就绪状态中的线程获得了 CPU 执行资源,执行线程函数中的代码,这样的线程我们称为运行状态的线程。
  • 阻塞状态(blocked):处于运行中的线程,由于某种原因放弃对 CPU 的使用权,处于阻塞状态,此时线程被挂起,不再执行,直到其进入就绪状态,才有机会再次被 CPU 调用进入运行状态。这种阻塞状态可能由多种原因导致,比如调用 sleep,信号量,锁等方式。
  • 终止状态(dead):线程在完成执行或异常中止时进入终止状态。

线程调度机制

线程清除

  1. import _thread
  2. import utime
  3. # 线程函数入口,实现每隔一秒进行一次打印。
  4. def thread_func_entry(id, name):
  5. while True:
  6. print( 'thread {} name is {}.'.format(id, name))
  7. utime.sleep(1)
  8. # 创建线程
  9. thread_id = _thread.start_new_thread(thread_func_entry, (1, 'QuecPython'))
  10. # 延时 10 秒后删除每秒打印线程。
  11. utime.sleep(10)
  12. _thread.stop_thread(thread_id)

互斥锁

互斥锁是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制。互斥锁目的通过将代码切片成一个一个的临界区域,以达到对临界区域保护作用,使得多线程能够顺序访问。

  1. # 该示例线程 B 一定条件下通过互斥锁控制线程 A 运行,达到线程间通信目的。
  2. import _thread
  3. import utime
  4. lock = _thread.allocate_lock()
  5. count = 1
  6. # 线程 B 函数入口,通过锁控制,防止同时操作操作全局变量count。
  7. def thread_entry_B(id):
  8. global count
  9. while True:
  10. with lock:
  11. print( 'thread {} count {}.'.format(id, count))
  12. count += 1
  13. utime.sleep(1)
  14. # 线程 A 函数入口,通过锁控制,防止同时操作操作全局变量count。
  15. def thread_entry_A(id):
  16. global count
  17. while True:
  18. with lock:
  19. print('thread {} count {}.'.format(id, count))
  20. count += 1
  21. # 创建线程
  22. _thread.start_new_thread(thread_entry_A, ('A',))
  23. _thread.start_new_thread(thread_entry_B, ('B',))