Python10 python多线程

图片

1.什么是python多线程

Python的多线程指的是在一个Python程序中同时运行多个线程,以达到并发执行多个任务的目的。线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。

在Python中,多线程的实现通常依赖于内置的threading模块,这个模块允许用户创建和管理线程。使用多线程可以使得程序能够在等待某些事件(如输入/输出操作)完成时,继续执行其他任务,从而提高程序的整体效率和响应速度。

Python多线程的特点:
  • 全局解释器锁(GIL):Python的标准实现(CPython)中有一个称为全局解释器锁(GIL)的机制,它确保任何时候只有一个线程执行Python字节码。这意味着即便是在多核处理器上,使用多线程也不会带来线程真正并行执行的性能提升。因此,Python的多线程主要适用于处理I/O密集型任务,而不是计算密集型任务

  • 并发而非并行:由于GIL的存在,Python的多线程更多的是实现并发执行,而不是真正的并行执行。并发意味着任务在宏观上同时进行,但在任一时刻,实际上只有一个任务在单个CPU核心上运行。

  • 适用场景:Python多线程非常适合I/O密集型任务,比如网络交互、文件读写等,因为在这些操作中,线程的大部分时间都在等待外部事件完成,而CPU计算需求不高。

2.单线程

下面的示例代码展示了单线程执行的线性特性,即程序中的任务按照它们被调用的顺序依次执行。每个任务都必须等待前一个任务完成后才能开始执行。这种方式在处理涉及等待或延时的任务时可能不够高效,因为它不能同时进行多个任务。

代码示例:

from time import ctime,sleep  # 从time模块导入ctime和sleep函数,ctime用于获取当前时间并以易读的字符串形式返回,sleep用于使程序暂停执行指定的秒数
print('当前时间是:%s'%ctime())  # 打印当前的时间,%s是格式化字符串,用于在字符串中插入变量,这里插入的是ctime()函数返回的当前时间字符串

# 单线程
from time import ctime,sleep
# 定义两个函数 music和movie用于模拟听音乐和看电影的活动
def music(what):
    # 在每个函数内部有一个for循环,循环两次,每次循环打印当前正在进行的活动及当前的时间,然后通过sleep(1)暂停1秒,模拟正在进行活动的时间消耗
    for i in range(2):
        print("我正在听音乐:%s,当前时间是:%s"%(what,ctime()))
        sleep(1)
def movie(what):
    for i in range(2):
        print("我正在看电影:%s,当前时间为:%s"%(what,ctime()))
        sleep(1)
music('你曾是少年')
movie('泰坦尼克号')
print('今天结束,当前时间为:%s'%ctime())

运行结果:

图片

3.多线程

下面的示例代码展示了如何使用Python的threading模块来创建和运行多线程程序,通过这种方式,可以同时执行多个任务。但是需要注意的是,由于设置了守护线程 (Daemon Threads),所以两个活动在主线程结束后也终止了,实际并没有按照设定的运行时间完成。守护线程表示当一个线程被设置为守护线程后,它就代表不重要的或在后台运行的服务。最重要的是,当所有非守护线程(即主线程)结束时,守护线程会被强制终止。

# 多线程
from time import ctime,sleep
import threading

def music(what):
    for i in range(2):
        print("我正在听音乐:%s,当前时间是:%s"%(what,ctime()))
        sleep(2)
def movie(what):
    for i in range(2):
        print("我正在看电影:%s,当前时间为:%s"%(what,ctime()))
        sleep(5)
# 开启线程
# 创建一个空列表 threads,用于存储所有线程
# 创建两个线程对象 th1 和 th2,分别指定目标函数music和movie,以及传递给这些函数的参数
# 将创建的线程对象添加到threads列表中
threads=[]
th1=threading.Thread(target=music,args=('你曾是少年',))
threads.append(th1)
th2=threading.Thread(target=movie,args=('泰坦尼克号',))
threads.append(th2)

# 执行线程
for th in threads:  # 循环遍历threads列表,启动每个线程
    th.daemon=True  # 使用setDaemon(True)将线程设置为守护线程。守护线程是一种在后台运行的线程,它的运行不会阻止主程序退出。当主程序退出时,守护线程会被自动终止。
    th.start()  # 使用start()方法启动线程
print('*****:听音乐和看电影结束{}'.format(ctime()))

# 在多线程环境中,线程的执行顺序和完成时间是不确定的,依赖于操作系统的线程调度
# 在.py执行后,从执行结果来看,子线程(muisc 、move )和主线程(print('*****:听音乐和看电影结束{}'.format(ctime())))都是同一时间启动,但由于主线程执行完结束,所以导致子线程也终止

运行结果:

图片

可以通过阻塞主线程的方式 th.join() 来实现确保音乐和电影的活动能够完全完成。

# 多线程
from time import ctime,sleep
import threading

def music(what):
    for i in range(2):
        print("我正在听音乐:%s,当前时间是:%s"%(what,ctime()))
        sleep(2)
def movie(what):
    for i in range(2):
        print("我正在看电影:%s,当前时间为:%s"%(what,ctime()))
        sleep(5)
# 开启线程
threads=[]
th1=threading.Thread(target=music,args=('丑八怪',))
threads.append(th1)
th2=threading.Thread(target=movie,args=('摔跤吧爸爸',))
threads.append(th2)

# 执行线程
for th in threads:
    th.daemon=True
    th.start()
th.join()  # 阻塞主线程
print('*****:听音乐和看电影结束{}'.format(ctime()))

运行结果:

图片

4.单&多线程对比

import threading  # 导入threading包
from time import sleep
import time
 
def task1(): 
    print ("Task 1 executed." )
    sleep(3)
 
def task2():
    print ("Task 2 executed." )
    sleep(5)
     
print("多线程:")
starttime=time.time();  # 记录开始时间
threads = []  # 创建一个线程列表,用于存放需要执行的子线程
t1 = threading.Thread(target=task1)  # 创建第一个子线程,子线程的任务是调用task1函数,注意函数名后不能有()
threads.append(t1)  # 将这个子线程添加到线程列表中
t2 = threading.Thread(target=task2)  # 创建第二个子线程
threads.append(t2)  # 将这个子线程添加到线程列表中
 
for t in threads:  # 遍历线程列表
    t.daemon=True  # 将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起
    t.start() #启动子线程
for t in threads:  # 再次遍历线程列表
    t.join()  # 等待每个线程完成
    
endtime=time.time()  # 记录程序结束时间
totaltime=endtime-starttime  # 计算程序执行耗时
print ("耗时:{0:.5f}秒" .format(totaltime))  # 格式输出耗时
print('---------------------------')
 
# 以下为普通的单线程执行过程
print("单线程:")
starttime=time.time()
task1()
task2()
endtime=time.time()
totaltime=endtime-starttime
print ("耗时:{0:.5f}秒" .format(totaltime))
print('主线程')

运行结果:

图片

5.创建和管理定时任务

示例代码演示了如何在 Python 中使用 threading.Timer 类来创建和管理定时任务。threading.Timer 是线程模块中的一个功能,用于在指定的时间后执行一个函数,并且可以重复设置以周期性地执行。

import threading
import time

def fun_timer():  # 定义计时器函数
    print("hello timer")  # 每次调用计时器函数,打印hello timer
    global timer
    timer=threading.Timer(2.5,fun_timer)  # 创建一个新的 threading.Timer 对象。这个定时器被设置为 2.5 秒后再次执行 fun_timer 函数,实现定时任务的周期性执行
    timer.start()  # 启动定时器
timer=threading.Timer(1,fun_timer)  # 初始化一个定时器,设置为1秒后执行fun_timer函数,这是整个周期性执行的起点
timer.start()  # 激活定时器
time.sleep(15)  # time.sleep(15)会让主线程暂停15秒,期间fun_timer将被周期性地调用
timer.cancel()  # 停止定时器

运行结果:

图片

以上内容总结自网络,如有帮助欢迎转发,我们下次再见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/722864.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Hudi】基础概念-数据写

目录 数据写写操作写流程(UPSERT)写流程(Insert)写流程(Insert Overwrite)Key生成策略删除策略 数据写 写操作 UPSERT:默认行为,数据先通过index打标,有一些启发式算法决定消息的组织以及优化文件的大小>CDC导入INSERT:跳过index,写入效…

(已解决) Github无法显示图像问题

Github无法显示图像的问题 问题描述初次尝试最终解决 问题描述 今天打开github,创建了一个仓库,想从本地把一些最近做的东西传上来(git add . > git commit -m “xxx” > git push),结果发现东西是成功传上来了,但是图片没…

简单好用的C++日志库spdlog使用示例

文章目录 前言一、spdlog的日志风格fmt风格printf风格 二、日志格式pattern三、sink,多端写入四、异步写入五、注意事项六、自己封装了的代码usespdlog.h封装代码解释使用示例 前言 C日志库有很多,glog,log4cpp,easylogging, eas…

PDF为何成为职场必备?编辑不求人,这几款工具助你一臂之力

不管是工作和学习,我们使用PDF文档的频率非常高,但是说起为什么要用PDF,却又只知其一不知其二。 为什么我们需要PDF? PDF,全称为Portable Document Format(可移植文件格式),是一种…

【电机】PID参数整定方法

1 试凑法 采样周期的选择,要根据所设计的系统的具体情况,用试凑的方法,在试凑过程中根据各种合理的建议来预选采样周期,多次试凑,选择性能较好的一个作为最后的采样周期。早整定参数时必须要认真的观察系统的相应情况…

低代码专题 | 低代码开发平台怎么收费,价格多少?一文揭秘!

低代码开发平台近几年真的火得一塌糊涂,不少企业都开始关注并尝试这种新的开发方式。 然而,关于低代码开发平台的收费问题,却是众说纷纭、信息零散。为了帮助大家更清晰地了解低代码开发平台的收费情况,这篇文章将进行全面的解读…

【STM32】使用标准库检测按键

按键检测使用到GPIO外设的基本输入功能。 1.硬件设计 作者使用的硬件没有按键模块。故使用了一个引脚模拟按键,将PWM1引脚拉低表示按键按下。思路如下:PWM1配置为输入,默认拉高,PWM1手动接地来模拟按下按键,此时PWM&a…

如何做好亚马逊、速卖通自养号测评?这些细节很重要

亚马逊,作为电商领域的领军者,吸引了无数卖家入驻。在这片竞争激烈的土地上,Review成为了卖家们展现实力、赢得消费者信任的关键。 Review不仅反映了产品的质量和卖家的服务,更是消费者选择购买的重要因素。因此,对于卖…

收入公平性评估方法

一、Gini系数## 1.1什么是基尼系数## 基尼系数是国际上用来综合考察居民内部收入分配差异状况的一个重要分析指标。每个人的收入有多有少,差距大时,基尼系数就高;差距小时,基尼系数就低。 1.2基本概念## 基尼系数表示在全部居民收…

js语法---理解防抖原理和实现方法

什么是防抖(节流) 在实际的网页交互中,如果一个事件高频率的触发,这会占用很多内存资源,但是实际上又并不需要监听触发如此多次这个事件(比如说,在抢有限数量的优惠券时,用户往往会提…

golang windows打包为linux可执行文件

使用go的交叉编译功能 set GOOSlinux set GOARCHamd64然后再执行go build 可能会报异常, 所以贴出我的go env配置仅供参考 go env环境配置 D:\GoWork\src\go-tzv>go env set GO111MODULEauto set GOARCHamd64 set GOBIN …

架构师篇-1、总体架构设计

业务架构哲学本质 定位:赋予业务架构设计能力,具备业务架构设计思维模型,掌握业务架构哲学本质,形成以不变应万变的业务架构设计能力。 架构师所需要的能力: 带领业务成功通过框架思维赋能业务架构师知识体系构建掌…

华北水利水电大学-C程序设计作业

目录 基础题 1-1 分析 代码实现 1-2 分析 代码实现 1-3 分析 代码实现 1-4 ​编辑 分析 代码实现 1-5 分析 代码实现 1-6 分析 代码实现 基础题 1-1 从键盘输入10个学生的有关数据,然后把它们转存到磁盘文件上去。其中学生信息包括学号、姓名…

学会python——制作一款天气查询工具(python实例七)

目录 1、认识Python 2、环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3、天气查询工具 3.1 代码构思 3.2 代码示例 3.3 运行结果 4、总结 1、认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的…

pip安装总是失败,如何配置pip安装源,让环境重获新生?

前情提要 公司新项目组报道后,因为用的是公司内网,安装完python 和pycharm 后,发现pip 下载安装包总是报错 具体解决 1.确认python 环境已经安装 2.在cmd中执行如下命令配置参数 pip config set global.index-url https://这里填写自己公…

Linux 软件包管理器 yum

文章目录 yum是什么?Linux(centos)的生态yum的相关操作yum本地配置安装包lrzsz yum是什么? yum可以形象的比喻成一个下载安装管理的一个客户端,比如小米应用商店、华为应用商城 Linux中的安装包是有依赖关系的(比如下载游戏的时候有各种文件…

神经网络模型---ResNet

一、ResNet 1.导入包 import tensorflow as tf from tensorflow.keras import layers, models, datasets, optimizersoptimizers是用于更新模型参数以最小化损失函数的算法 2.加载数据集、归一化、转为独热编码的内容一致 3.增加颜色通道 train_images train_images[...,…

滑动窗口练习1-长度最小的子数组

1.题目链接:209.长度最小的子数组 2.题目描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条…

【机器学习】第9章 降维算法——PCA降维

一、概念 1.PCA (1)主成分分析(Principal ComponentAnalysis,PCA)一种经典的线性降维分析算法。 (2)原理,这里以二维转一维为例,原来的平面变成了一条直线 这是三维变二…

git 基本命令

列出分支基本命令: git branch 如果我们要手动创建一个分支 。执行 git branch (branchname) 即可: git branch testing 切换到testing分支: git checkout testing 我们也可以使用 git checkout -b (branchname) 命令来创建新分支并立…