IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> Python | threading01 - 创建两个同时运行的子线程 -> 正文阅读

[嵌入式]Python | threading01 - 创建两个同时运行的子线程

一、前言


在这里插入图片描述
使用threading库,咱们的python程序就能从单线程串行变成多线程并发。python的threading库实现的“并发”是假的并发,即同一时刻只有一个线程在运行。据说python后来想将这个假的“并发”改为真的并发,但出现特别多的BUG,最后放弃了这个想法。

聊到假的“并行”,学习过单片机(STM32)的嵌入式实时系统RTOS(ucosIII、freeRTOS、RTX5等)的同学就知道,移植了RTOS的单片机,同一时刻仅仅只有一个线程在运行。只是RTOS在很快的切换线程,产生了好像多个线程在同时工作的“假象”。

二、创建两个同时运行的线程


2.1、代码

# python3.9
import time
import threading

def thread1():
    """
    线程1
    """
    while True:
        # 打印信息,并打印性能计数器的值
        print("I am thread1,time is %f" % time.perf_counter())
        time.sleep(1)  # 休眠1秒
    
def thread2():
    """
    线程2
    """
    while True:
        # 打印信息,并打印性能计数器的值
        print("I am thread2,time is %f" % time.perf_counter())
        time.sleep(1)  # 休眠1秒

def main():
    """
    主线程
    """
    t1 = threading.Thread(target=thread1) # 创建thread1线程
    t2 = threading.Thread(target=thread2) # 创建thread2线程
    t1.start()  # 启动thread1线程
    t2.start()  # 启动thread2线程

if __name__ == "__main__":
    main()

2.2、运行

从下图可以看到,线程1与线程2都是每隔约1秒时间运行一次。线程1与线程2哪个先运行取决于系统的调度。
在这里插入图片描述

三、threading库的函数


3.1、threading.Thread()

在这里插入图片描述
入口参数:

  • group - 暂时不使用
  • target - 用于执行线程需要执行的线程函数
  • name - 可以自定义线程的名字,不设置的话,系统就自动分配
  • args - 创建线程时,可以给线程函数传递参数
  • kwargs - 暂时不使用
  • daemon - 设置线程是否为守护线程(后台线程)

当我们不对入口参数name赋值的话,系统会自动分配线程名字。
在这里插入图片描述
运行代码:
在这里插入图片描述
接着,我尝试对入口参数name进行赋值。
在这里插入图片描述
运行代码:
在这里插入图片描述
另外一个重要的入口参数是daemon,它的作用是设置线程是否为守护线程(后台线程)。守护线程有一个重要的特点是主线程(例子的main()线程)退出时,守护线程不管怎样都要跟主线程一起退出。
守护线程的目的与作用:
在这里插入图片描述
所以,我的理解是:当创建的子线程是无限循环的话,就应该设置为守护线程。随着主线程的退出,子线程被强制退出,保证了整个python程序正常地,完整地退出。
在这里插入图片描述
运行结果:
main()线程退出,线程t1与t2也跟着退出了。有什么办法解决这个问题?
在这里插入图片描述

3.2、threading.join()

join()方法可以让主线程进入阻塞态,等待其他线程运行结束,接着才解除阻塞态。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3、threading.start()

start()方法用于启动线程的运行,否则线程不会跑起来。
在这里插入图片描述

四、最终的完整代码


  1. 使用守护线程,主线程退出时,强制让所有的子线程退出,确保整个python程序正常地退出。
  2. 使用threading.join()方法,让主线程等子线程结束,无限循环的子线程可以持续无限执行。
# python3.9
import time
import threading

def thread1():
    """
    线程1
    """
    while True:
        # 打印信息,并打印性能计数器的值
        print("I am thread1,time is %f" % time.perf_counter())
        time.sleep(1)   # 休眠1秒
    
def thread2():
    """
    线程2
    """
    while True:
        # 打印信息,并打印性能计数器的值
        print("I am thread2,time is %f" % time.perf_counter())
        time.sleep(1)   # 休眠1秒

def main():
    """
    主线程
    """
    t1 = threading.Thread(target=thread1,name="fun_thread1",daemon=True) # 创建thread1线程
    t2 = threading.Thread(target=thread2,name="fun_thread2",daemon=True) # 创建thread2线程
    t1.start()  # 启动thread1线程
    t2.start()  # 启动thread2线程
    print("t1的线程名字是 %s" % t1.getName()) # 打印t1线程的线程名字
    print("t2的线程名字是 %s" % t2.getName()) # 打印t2线程的线程名字
    t1.join()   # 当前需要等待线程t1执行完毕后才能运行下一步
    t2.join()   # 当前需要等待线程t2执行完毕后才能运行下一步
    print("主线程执行完毕!")
    
if __name__ == "__main__":
    main()
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 16:16:35  更:2022-01-03 16:16:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 4:25:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码