【python学习】多线程编程的背景、定义、特点、优缺点、使用场景和示例以及和单线程的区别

news2024/11/13 23:38:05

引言

随着计算机技术的发展,多核处理器已经成为了主流,为了充分利用多核处理器带来的并行计算能力,提高程序的执行效率和响应速度,多线程编程变得尤为重要
Python作为一种高级编程语言,提供了多线程编程的支持,允许开发者创建能够在后台执行任务的线程,从而实现程序的并发执行

文章目录

  • 引言
  • 一、定义
  • 二、特点
    • 2.1 并发性
    • 2.2 资源共享
    • 2.3 轻量级
  • 三、优点
    • 3.1 提高程序响应性
    • 3.2 改善资源利用率
    • 3.3 简化程序结构
  • 四、缺点
    • 4.1 全局解释器锁(GIL)
    • 4.2 线程安全问题
    • 4.3 调试困难
  • 五、使用场景
    • 5.1 I/O密集型任务
    • 5.2 图形用户界面(GUI)应用
    • 5.3 并行任务分解
  • 六、示例
  • 七、多线程编程与单线程的区别
    • 7.1 执行模型
      • 7.1.1 单线程编程
      • 7.1.2 多线程编程
    • 7.2并行与并发
      • 7.2.1 单线程编程
      • 7.2.2 多线程编程
    • 7.3 性能
      • 7.3.1 单线程编程
      • 7.3.2 多线程编程
    • 7.4 复杂性
      • 7.4.1 单线程编程
      • 7.4.2 多线程编程
    • 7.5 同步和线程安全
      • 7.5.1 单线程编程
      • 7.5.2 多线程编程
    • 7.6 示例对比
      • 7.6.1 单线程示例
      • 7.6.2 多线程示例
  • 八、总结(思维导图)

一、定义

Python多线程编程是指在Python程序中创建并管理多个线程的过程
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位
Python中,通常使用threading模块来创建和管理线程。

二、特点

2.1 并发性

线程可以在同一程序内并发执行,使得程序能够同时处理多个任务

2.2 资源共享

线程共享进程的内存和资源,因此它们之间通信和数据共享相对容易

2.3 轻量级

线程比进程更加轻量级,创建和销毁线程的开销小于进程

三、优点

3.1 提高程序响应性

在执行I/O密集型任务时,多线程可以让程序在等待I/O操作完成的同时继续执行其他任务。

3.2 改善资源利用率

由于线程共享内存和资源,可以减少资源消耗。

3.3 简化程序结构

通过将复杂的任务分解为多个线程,可以使程序结构更加清晰。

四、缺点

4.1 全局解释器锁(GIL)

Python中,由于GIL的存在,即使在多核处理器上,同一时间也只能有一个线程执行Python字节码,限制了线程的并行执行能力

4.2 线程安全问题

线程共享内存可能导致数据竞争和同步问题,需要额外的机制来保证线程安全

4.3 调试困难

线程间的交互可能导致难以追踪和重现的问题

五、使用场景

5.1 I/O密集型任务

如网络请求、文件读写等,线程在等待I/O操作时可以释放GIL,让其他线程运行

5.2 图形用户界面(GUI)应用

在GUI应用中,主线程通常用于处理用户界面事件,而多线程可以用于后台任务,以保持界面的响应性

5.3 并行任务分解

可以将一个大任务分解为多个小任务,由不同的线程并行执行

六、示例

以下是一个简单的Python多线程编程示例,演示了如何在程序中创建两个线程,分别执行不同的任务

import threading
import time
# 定义一个函数供线程执行
def print_numbers():
    for i in range(1, 10):
        print(i)
        time.sleep(0.5)  # 模拟I/O操作
# 定义另一个函数供线程执行
def print_letters():
    for letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
        print(letter)
        time.sleep(0.5)  # 模拟I/O操作
# 创建两个线程
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)
# 启动线程
thread1.start()
thread2.start()
# 等待线程结束
thread1.join()
thread2.join()
print("线程执行完毕。")

在这个示例中,我们定义了两个函数print_numbersprint_letters,分别用于打印数字和字母。每个函数都包含一个time.sleep调用,模拟I/O操作。我们创建了两个线程thread1thread2,分别执行这两个函数。通过调用start()方法启动线程,并通过join()方法等待线程执行结束。这个例子展示了如何在Python中使用多线程来并发执行任务。

七、多线程编程与单线程的区别

7.1 执行模型

7.1.1 单线程编程

在单线程编程中,程序按照代码的顺序依次执行,一次只能执行一个任务。如果当前任务需要等待(如I/O操作),整个程序都会等待,直到该任务完成。

7.1.2 多线程编程

多线程编程允许程序同时执行多个线程,每个线程可以看作是一个独立的执行流。这使得程序能够在等待一个线程执行I/O操作时,在另一个线程中继续执行其他任务。

7.2并行与并发

7.2.1 单线程编程

单线程程序通常是顺序执行的,即使在多核处理器上,也不能真正实现并行计算。

7.2.2 多线程编程

多线程程序可以在多核处理器上实现真正的并行计算,尽管在CPython中由于全局解释器锁(GIL)的存在,纯Python代码的并行执行受到限制。

7.3 性能

7.3.1 单线程编程

对于CPU密集型任务,单线程程序通常能够充分利用单个CPU核心的性能。对于I/O密集型任务,单线程程序可能会因为等待I/O操作而造成性能瓶颈。

7.3.2 多线程编程

对于I/O密集型任务,多线程可以提高程序的响应性和性能,因为它可以在一个线程等待I/O操作时,让其他线程继续执行。然而,对于CPU密集型任务,多线程在CPython中可能不会带来性能上的提升,甚至可能因为线程切换和GIL的存在而导致性能下降。

7.4 复杂性

7.4.1 单线程编程

单线程程序的逻辑通常更简单,因为它们顺序执行,没有线程之间的交互和同步问题。

7.4.2 多线程编程

多线程程序更加复杂,因为需要处理线程之间的资源共享、同步(如使用锁、信号量等)以及可能的死锁和竞态条件。

7.5 同步和线程安全

7.5.1 单线程编程

在单线程环境中,不需要担心线程安全问题,因为只有一个线程在操作数据。

7.5.2 多线程编程

在多线程环境中,必须确保线程安全,防止多个线程同时修改同一数据,导致数据不一致或程序崩溃。

7.6 示例对比

以下是一个单线程与多线程的简单对比示例:

7.6.1 单线程示例

import time
def task(name, delay):
    for i in range(5):
        print(f"Task {name}: Iteration {i}")
        time.sleep(delay)
start_time = time.time()
task("A", 1)
task("B", 2)
end_time = time.time()
print(f"Total time: {end_time - start_time} seconds")

在这个单线程示例中,任务A和任务B将依次执行,总执行时间将是两个任务执行时间的总和。

7.6.2 多线程示例

import threading
import time
def task(name, delay):
    for i in range(5):
        print(f"Task {name}: Iteration {i}")
        time.sleep(delay)
start_time = time.time()
thread1 = threading.Thread(target=task, args=("A", 1))
thread2 = threading.Thread(target=task, args=("B", 2))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
end_time = time.time()
print(f"Total time: {end_time - start_time} seconds")

在这个多线程示例中,任务A和任务B将并发执行,总执行时间将接近于执行时间较长的那个任务,因为它们是并行执行的。

总结来说,多线程编程可以提升程序的并发性和响应性,但也带来了额外的复杂性和线程安全问题
单线程编程则更加简单,但无法充分利用多核处理器的能力。选择多线程还是单线程编程取决于具体的应用场景和需求。

八、总结(思维导图)

在这里插入图片描述

PS:知识内容部分取自:https://www.runoob.com/python/python-multithreading.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣 24两两交换链表中节点

画图 注意有虚拟头结点 注意判断时先判断cur->next ! nullptr,再判断cur->next->next ! nullptr 注意末尾返回dumyhead->next,用新建result指针来接并返回 class Solution { public:ListNode* swapPairs(ListNode* head) {ListNode *dummyhead new …

【2024_CUMCM】时间序列1

目录 概念 时间序列数据 时期和时点时间序列 数值变换规律 长期趋势T 季节趋势S 循环变动C 不规则变动I 叠加和乘积模型 叠加模型 相互独立 乘积模型 相互影响 注 spss缺失值填补 简单填补 五种填补方法 填补原则 1.随机缺失 2.完全随机缺失 3.非随机缺失…

WGCLOUD登录页面支持输入验证码吗

支持的 v3.5.3版本开始,WGCLOUD支持在登录页面配置输入验证码,我们可以根据自己的场景需要,配置是否在登录页面显示验证码,如下说明 登录页面添加验证码说明 - WGCLOUD

酒店管理系统小程序的设计

管理员账户功能包括:系统首页,个人中心,用户管理,酒店管理员管理,房间类型管理,房间信息管理,订单信息管理,系统管理 微信端账号功能包括:系统首页,房间信息…

CycleGAN深度学习项目

远程仓库 leftthomas/CycleGAN: A PyTorch implementation of CycleGAN based on ICCV 2017 paper "Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks" (github.com) 运行准备 Anaconda 安装需要的库 指令 pip install panda…

AI时代:探索个人潜能的新视角

文章目录 Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉 1.5.2 局限二:Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 3 人工智能发…

万界星空科技商业开源MES系统全面解析

万界星空科技商业开源MES源码可拖拽式数据大屏 开源MES系统具有定制化、节省成本、开放性和适应性等优势和特点,可以帮助企业更好地管理生产流程。万界星空MES制造执行系统的Java开源版本,为制造业企业提供了全面的生产管理解决方案。万界星空科技的目标…

从零开始做题:满屏的QR

题目 给出一张png图片 解题 import os import re import cv2 import argparse import itertools import numpy as npparser argparse.ArgumentParser() parser.add_argument(-f, typestr, defaultNone, requiredTrue,help输入文件名称) parser.add_argument(-p, typestr, d…

[Vulnhub] Stapler wp-videos+ftp+smb+bash_history权限提升+SUID权限提升+Kernel权限提升

信息收集 IP AddressOpening Ports192.168.8.106TCP:21,22,53,80,123,137,138,139,666,3306, Using Nmap for scanning: $ nmap -p- 192.168.8.106 --min-rate 1000 -sC -sV The results are as follows: PORT STATE SERVICE VERSION 20/tcp closed ftp-data…

昇思25天学习打卡营第20天 | 基于MindNLP+MusicGen生成自己的个性化音乐

基于MindNLPMusicGen生成个性化音乐 实验简介 MusicGen是Meta AI提出的音乐生成模型,能够根据文本描述或音频提示生成高质量音乐。该模型基于Transformer结构,分为三个阶段:文本编码、音频token预测和音频解码。此实验将演示如何使用MindSpo…

Java常用排序算法

冒泡排序(Bubble Sort) arr[0] 与 arr[1]比较,如果前面元素大就交换,如果后边元素大就不交换。然后依次arr[1]与arr[2]比较,第一轮将最大值排到最后一位。 第二轮arr.length-1个元素进行比较,将第二大元素…

高速数据采集与图像传输对带宽需求的对比分析

对于120MHz高速采集的数据,直接传输原始数据和将数据计算生成1024x1024的图像后再传输图像,这两种方法对带宽的影响会有显著不同。为了进行详细分析,我们需要考虑以下因素:数据采样率、数据量、图像生成算法、图像压缩和传输带宽需…

Spark调度底层执行原理详解(第35天)

系列文章目录 一、Spark应用程序启动与资源申请 二、DAG(有向无环图)的构建与划分 三、Task的生成与调度 四、Task的执行与结果返回 五、监控与容错 六、优化策略 文章目录 系列文章目录前言一、Spark应用程序启动与资源申请1. SparkContext的创建2. 资…

python:绘制一元四次函数的曲线

编写 test_x4_x2_4x.py 如下 # -*- coding: utf-8 -*- """ 绘制函数 y x^4x^24x-3 在 -2<x<2 的曲线 """ import numpy as np from matplotlib import pyplot as plt# 用于正常显示中文标题&#xff0c;负号 plt.rcParams[font.sans-s…

值得关注的数据资产入表

不错的讲解视频&#xff0c;来自&#xff1a;第122期-杜海博士-《数据资源入表及数据资产化》-大数据百家讲坛-厦门大学数据库实验室主办第122期-杜海博士-《数据资源入表及数据资产化》-大数据百家讲坛-厦门大学数据库实验室主办-20240708_哔哩哔哩_bilibili

《昇思25天学习打卡营第20天|onereal》

应用实践/LLM原理和实践/基于MindSpore的GPT2文本摘要 基于MindSpore的GPT2文本摘要 数据集加载与处理 数据集加载 本次实验使用的是nlpcc2017摘要数据&#xff0c;内容为新闻正文及其摘要&#xff0c;总计50000个样本。 数据预处理 原始数据格式&#xff1a; article: [CLS…

java框架-springmvc

文章目录 2. Springmvc概述3. springmvc与struts2不同5. springmvc入门6. springmvc 配置7. Handler配置8. 异常处理器9. ssm整合思路10. 上传图片11. RESTful支持12. 拦截器总结 2. Springmvc概述 Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分 3. sp…

QML 鼠标和键盘事件

学习目标&#xff1a;Qml 鼠标和键盘事件 学习内容 1、QML 鼠标事件处理QML 直接提供 MouseArea 来捕获鼠标事件&#xff0c;该操作必须配合Rectangle 获取指定区域内的鼠标事件, 2、QML 键盘事件处理&#xff0c;并且获取对OML直接通过键盘事件 Keys 监控键盘任意按键应的消…

防御第二次作业完成接口配置实验

一、实验括扑图 二、实验要求 1.防火墙向下使用子接口分别对应生产区和办公区 2.所有分区设备可以ping通网关 三、实验思路 1、配置各设备的IP地址 2、划分VLAN及VLAN的相关配置 3、配置路由及安全策略 四、实验步骤 1、配置PC跟Client还有server配置&#xff0…

Hive表【汇总】

提前必备 1、内部表和外部表的区别 概念讲解&#xff1a; 外部表&#xff1a;1、存放他人给予自己的数据2、当我们删除表操作时&#xff0c;会将表的元数据删除&#xff0c;保留数据文件 内部表&#xff1a;1、存放已有的数据2、当我们删除表操作时&#xff0c;会将表的元数据…